【问题标题】:Fast array chunking in Node.jsNode.js 中的快速数组分块
【发布时间】:2018-10-11 00:56:09
【问题描述】:

我正在处理长数据集的数组分块。我需要创建一个新的一定大小的块数组。目前,我使用这个解决方案,但它表现不佳。

function array_to_chunks(data, size){
   let chunks = []
   let d = data.slice()
   while (d.length >= size) chunks.push(d.splice(0, size))
   return chunks
}

我想找到一些更好的想法,了解如何以足够快的速度完成它以及为什么我的代码表现不佳。

【问题讨论】:

  • 你在使用 I/O 吗?如果是这样,请使用 Node.js 流。否则,您将缓冲所有内容。
  • 不,我不知道。实际上,由于项目当前的状态,这是不可能的。
  • 绝对使用WritableStream 的一个或子类。
  • 我添加了另一个想法。有兴趣听听您对性能的看法。

标签: javascript arrays node.js chunks array-splice


【解决方案1】:

这稍微提高了性能,因为您不必复制数组:

const createGroupedArray = function (arr, chunkSize) {

    if (!Number.isInteger(chunkSize)) {
        throw 'Chunk size must be an integer.';
    }

    if (chunkSize < 1) {
        throw 'Chunk size must be greater than 0.';
    }

    const groups = [];
    let i = 0;
    while (i < arr.length) {
        groups.push(arr.slice(i, i += chunkSize));
    }
    return groups;
};

如果您正在执行 I/O,则使用 Node.js 流:

const strm = new Writable({
  write(chunk, enc, cb){
     // do whatever
  }
});

【讨论】:

  • slightly more performant - 根据我的计算,它快了 400 倍!当然取决于原始数组大小和块大小(使其速度提高 700 倍以上)
  • 不幸的是,我必须复制它,因为“数据”正在被对象的其他方法访问(提供的代码是一种改编)
  • 我认为你误解了......你必须将它复制到你的代码中,因为.splice 改变了原来的...... .slice 不会改变原来的数组,因此,你不 需要复制它,因为原始数组保持不变
  • 你在说什么尺寸......例如,原始数组的长度和块的长度(注意,如果数组长度不是精确的倍数,我认为你的原始代码不会返回所有内容块大小
  • @JaromandaX,数组的每个元素约为 434 字节。数组长度约为 500,000 个条目
【解决方案2】:

你可以使用 lodash chunk 方法,这可以满足你的需要

const _ = require('lodash');
_.chunk([1,2,3,4,5,6],2);

【讨论】:

    【解决方案3】:

    我很想听听您对这种方法的意见:

    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
    const size = 5
    
    const chunkIt = (arr, size) => {
      let buckets = []
    
      // Just create the buckets/chunks storage
      for (let i = 1; i <= Math.ceil(arr.length / size); i++) {
        buckets.push([])
      }
    
      // Put in the buckets/storage by index access only
      for (let i = 0; i < arr.length; i++) {
        var arrIndex = Math.ceil((i + 1) / size) - 1
        buckets[arrIndex].push(arr[i])
      }
    
      return buckets;
    }
    
    console.log(chunkIt(arr, size))

    我做了一些基本的 JS 基准测试,效果很好。这个想法是预先创建存储桶,因为该操作不应该那么昂贵,然后只需按索引推送。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      • 2020-11-01
      • 2018-05-27
      • 2011-08-19
      • 1970-01-01
      相关资源
      最近更新 更多