You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenNTF Domino API:非起始位置获取ViewEntryCollection子集的高性能方法

优化OpenNTF Domino API获取ViewEntryCollection非起始子集的性能方案

针对从包含约5万条文档的ViewEntryCollection中,获取从第N条(N>0)开始的100条条目场景,已知循环调用getNthEntry性能差、普通for-each无法直接跳转到指定起始位置,以下是几种性能更优的实现方案:


方案1:单次定位起点+线性遍历

仅调用一次getNthEntry定位到起始条目,后续用navigateNext线性遍历目标数量的条目。此方案避免了循环调用getNthEntry的高开销,性能与for-each接近。

ViewEntryCollection vec = ...; // 获取目标集合
int startIndex = 1000; // 起始位置(需注意API的索引是0/1-based,此处以1-based为例)
int batchSize = 100;

// 仅调用一次getNthEntry定位起点
ViewEntry currentEntry = vec.getNthEntry(startIndex);
if (currentEntry == null) {
    vec.recycle();
    return;
}

int processedCount = 0;
try {
    while (processedCount < batchSize && currentEntry != null) {
        if (currentEntry.isDocument()) {
            // 处理当前文档条目
            processedCount++;
        }
        // 遍历下一条
        ViewEntry nextEntry = currentEntry.navigateNext();
        currentEntry.recycle(); // 及时回收已处理条目
        currentEntry = nextEntry;
    }
} finally {
    if (currentEntry != null) {
        currentEntry.recycle();
    }
    vec.recycle();
}

方案2:直接构建分页子集(适合频繁分页场景)

如果视图有明确的排序键,可通过createViewEntryCollectionByKey直接构建目标页的子集集合,无需加载整个大集合,性能和内存占用更优。

View view = database.getView("YourSortedView"); // 需是按指定字段排序的视图
int pageNumber = 5; // 目标页码
int pageSize = 100;
int startPosition = (pageNumber - 1) * pageSize + 1;

// 获取分页起始条目的键值
ViewEntry startEntry = view.getNthEntry(startPosition);
if (startEntry == null) {
    view.recycle();
    return;
}

try {
    Object startKey = startEntry.getKey();
    // 直接获取从startKey开始的pageSize条条目
    ViewEntryCollection pageVec = view.createViewEntryCollectionByKey(startKey, true, pageSize);
    
    for (ViewEntry ve : pageVec) {
        if (ve.isDocument()) {
            // 处理条目
        }
    }
    
    pageVec.recycle();
} finally {
    startEntry.recycle();
    view.recycle();
}

方案3:迭代器跳过前置条目

利用ViewEntryCollection的迭代器,手动跳过指定数量的前置条目后,再遍历目标数量的内容。底层逻辑与for-each一致,性能相当,且无需调用getNthEntry。

ViewEntryCollection vec = ...;
int skipCount = 1000; // 需要跳过的条目数
int takeCount = 100; // 需要获取的条目数

Iterator<ViewEntry> iterator = vec.iterator();
int skipped = 0;

// 跳过前置条目
while (iterator.hasNext() && skipped < skipCount) {
    ViewEntry ve = iterator.next();
    if (ve.isDocument()) {
        skipped++;
    }
    ve.recycle(); // 及时回收跳过的条目,避免内存泄漏
}

// 处理目标条目
int processed = 0;
while (iterator.hasNext() && processed < takeCount) {
    ViewEntry ve = iterator.next();
    if (ve.isDocument()) {
        // 处理条目
        processed++;
    }
    ve.recycle();
}

vec.recycle();

方案选择建议

  • 偶尔获取非起始子集:优先选择方案1或方案3,实现简单且性能稳定;
  • 频繁分页查询:优先选择方案2,能大幅降低内存占用并提升查询效率(前提是视图有可用的排序键)。

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:25:29