如何提高此 CSV 解析代码的性能?

问题描述

我正在尝试将大型 CSV 文件(准确地说是 this one)解析为从数字到对象的 Map。由于文件很大并且可能需要一段时间才能下载,因此代码会在下载过程中对其进行解析,以防止在下载完成后一次性完成所有工作。代码如下:

const unicodeDataReader = (await fetch("data/ucd/UnicodeData.txt")).body.getReader();

const decoder = new TextDecoder();
let chunk,done;
let codePoint,column = 0,fieldBytes = [],codePointObj = {};
while ({ value: chunk,done } = await unicodeDataReader.read(),!done) {
  for (const byte of chunk) {
    if (byte === 0x3B) { // ;
      const a = new Uint8Array(fieldBytes);
      const field = decoder.decode(a);
      switch (column) {
        case 0:
          codePoint = Number.parseInt(field,16);
          break;
        case 1:
          codePointObj.name = field;
          break;
        case 2:
          codePointObj.generalCategory = field;
          break;
      }
      fieldBytes.length = 0;
      column++;
    } else if (byte === 0x0A) { // \n
      ucd.codePoints.set(codePoint,codePointObj);
      fieldBytes.length = 0;
      column = 0;
      codePointObj = {};
    } else {
      fieldBytes.push(byte);
    }
  }
}

然而,这段代码的性能很差(即使是从 localhost 下载),我也不知道为什么。 Chrome DevTools 表示执行时间最长的代码行是:

const a = new Uint8Array(fieldBytes);
const field = decoder.decode(a);

最奇怪的是,这种类似的方法似乎工作得更好,但如果一个角色被分成两个块,它可能不起作用。 (此文件不会发生这种情况,因为只有 ASCII 字符,但我计划将此代码改编为其他类似文件。)

const unicodeDataReader = (await fetch("data/ucd/UnicodeData.txt")).body.getReader();

const decoder = new TextDecoder();
let chunk,field = "",!done) {
  for (const char of decoder.decode(chunk)) {
    if (char === ";") { // ;
      switch (column) {
        case 0:
          codePoint = Number.parseInt(field,16);
          break;
        case 1:
          codePointObj.name = field;
          break;
        case 2:
          codePointObj.generalCategory = field;
          break;
      }
      field = "";
      column++;
    } else if (char === "\n") { // \n
      ucd.codePoints.set(codePoint,codePointObj);
      field = "";
      column = 0;
      codePointObj = {};
    } else {
      field += char;
    }
  }
}

我认为问题在于 decoder.decode() 被调用太多,或者创建 Uint8Array 可能很慢,但这似乎不是问题,因为此代码运行速度非常快:

const td = new TextDecoder();
const decoded= [];
for (let i=0;i<10000;i++) {
  // Generate a Uint8Array with 100 random bytes
  const a = new Uint8Array(function*(){for(let i=0;i<100;i++)yield Math.floor(256*Math.random())}());
  const b = [];
  for (const byte of a)
    b.push(byte);
  const c = new Uint8Array(b);
  decoded.push(td.decode(c));
}

如何提高代码的性能?

P.S.:我没有启用网络节流。代码很慢,主线程冻结了几秒钟。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)