按索引获取OrderedMap元素的最佳方式(从速度/内存的角度)是什么?是map.toArray(index)
吗?如果是,这个操作的成本是多少?
序列是集合的包装器,允许对底层数据进行惰性访问。它们必须实例化一个很小的包装器类,但它几乎不需要内存。这个操作的复杂度是0(1)。要访问有序收集的API,只需使用map.toIndexedSeq().get(index)
或map.valueSeq().get(index);
。
map.toArray(index)
是一个昂贵的操作,因为它将整个不可变转换为原生javascript数组。它的复杂度至少是O(n)。
function valueSeq(coll, searchVal) {
return coll.valueSeq().get(searchVal);
}
function indexedSeq(coll, searchVal) {
return coll.toIndexedSeq().get(searchVal);
}
function toArray(coll, searchVal) {
return coll.toArray()[searchVal];
}
function toList(coll, searchVal) {
return coll.toList().get(searchVal);
}
function arrayRange(len) {
return new Array(len).fill(null).map((_, i) => `thing ${i}`);
}
function timeGet(checkWhat, coll, find, iters) {
let startTime = performance.now();
let size = coll.length || coll.size;
for (let i = 1; i < iters; i++) {
let searchVal = i % coll.size,
result = find(coll, searchVal);
if(result != `thing ${searchVal}`){
console.log('fail', searchVal, `"${result}"`);
}
}
return Math.floor(performance.now() - startTime);
}
const MIN_LEN = 10,
MAX_LEN = 1e4,
ITERS = 2000;
console.log('tttindexedSeqttoArraytttoListttkeyedSeq');
for (let len = MIN_LEN; len <= MAX_LEN; len *= 10) {
const immutOrderedSetRange = Immutable.OrderedSet(arrayRange(len));
console.log(`${len}ttt` +
`${timeGet('indexedSeq', immutOrderedSetRange, indexedSeq, ITERS)}tt` +
`${timeGet('toArray', immutOrderedSetRange, toArray, ITERS)}tt` +
`${timeGet('toList', immutOrderedSetRange, toList, ITERS)}tt` +
`${timeGet('valueSeq', immutOrderedSetRange, valueSeq, ITERS)}`)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.0.0-rc.12/immutable.js"></script>