迭代非常大的对象(100 万个键)时,Chromium 132 中存在错误

问题描述 投票:0回答:1

Chrome 132 中似乎存在一个错误,其中包含非常大的对象(100 万个键)。

  • 铬132.0.6834.84
  • V8 13.2.152.27

火狐浏览器运行良好

这是一个最小的重现。

  • 由于某种原因,chrome第一次加载页面时,只有2个错误。
  • 我刷新后,出现了3个错误。
<html>
  <script>
    const count = 1e6; // 1e5 => OK, 1e6 => ERROR

    const big = {};
    for (let i = 0; i < count; i++) {
      big[`key_${i}`] = { a: i, b: i * 2, c: i * 3 };
    }

    console.log('begin');

    try {
      for (let k in big) {
        if (big[k] === undefined) {
          throw new Error();
        }
      }
    } catch (e) {
      console.log(`for (k in big) => ERROR with count = ${count}`);
    }

    try {
      const keys = Object.keys(big);
      for (let k of keys) {
        if (big[k] === undefined) {
          throw new Error();
        }
      }
    } catch (e) {
      console.log(`Object.keys(big) => ERROR with count = ${count}`);
    }

    
    try {
      const keys = Object.getOwnPropertyNames(big);
      for (let k of keys) {
        if (big[k] === undefined) {
          throw new Error();
        }
      }
    } catch (e) {
      console.log(`Object.getOwnPropertyNames(big) => ERROR with count = ${count}`);
    }

    console.log('done');
  </script>
</html>
javascript google-chrome chromium v8
1个回答
0
投票

Chrome 132 在处理包含 100 万个或更多键的非常大的对象时似乎遇到了问题。在 Firefox 中未观察到此行为,表明这可能是 Chrome 特有的错误。为了防止 Chrome 132 中出现这些错误,您可以尝试以下方法: 将对象分块 您可以将其拆分为更小的块,而不是创建单个大对象: JavaScript

const chunkSize = 1e5; // 100,000 keys per chunk
const chunks = [];

for (let i = 0; i < count; i += chunkSize) {
  const chunk = {};
  for (let j = 0; j < chunkSize && i + j < count; j++) {
    chunk[`key_${i + j}`] = { a: i + j, b: (i + j) * 2, c: (i + j) * 3 };
  }
  chunks.push(chunk);
}

// Iterate over chunks
chunks.forEach(chunk => {
  for (let k in chunk) {
    if (chunk[k] === undefined) {
      throw new Error();
    }
  }
});

使用地图代替对象 对于大型集合,使用 Map 可以更高效且不易出现问题: JavaScript

const big = new Map();
for (let i = 0; i < count; i++) {
  big.set(`key_${i}`, { a: i, b: i * 2, c: i * 3 });
}

// Iterate over the Map
for (let [k, v] of big) {
  if (v === undefined) {
    throw new Error();
  }
}

延迟加载 如果您不需要一次需要所有数据,请考虑延迟加载或按需生成数据: JavaScript

function* generateBigObject() {
  for (let i = 0; i < count; i++) {
    yield [`key_${i}`, { a: i, b: i * 2, c: i * 3 }];
  }
}

const bigIterator = generateBigObject();

// Use the iterator as needed
for (let [k, v] of bigIterator) {
  if (v === undefined) {
    throw new Error();
  }
}

异步处理 为了避免阻塞主线程并可能触发超时,您可以异步处理数据: JavaScript

async function processBigObject() {
  const big = {};
  for (let i = 0; i < count; i++) {
    big[`key_${i}`] = { a: i, b: i * 2, c: i * 3 };
    if (i % 10000 === 0) {
      await new Promise(resolve => setTimeout(resolve, 0));
    }
  }
  return big;
}

processBigObject().then(big => {
  // Process the object here
});

这些方法应该有助于缓解您在 Chrome 132 中使用非常大的对象时遇到的问题。如果问题仍然存在,您可能需要将其作为错误报告给 Chromium 项目5。

© www.soinside.com 2019 - 2024. All rights reserved.