js 【 巨难问题 】如何用二进制位操作 替代for 循环减去每一项的算法?

发布于 2022-09-12 02:23:04 字数 152 浏览 10 评论 0

var arr = [12,45,45,323,542,34 .....] 长度是10万上

每一项减去 7 得到一个新数组

用for 还是太慢, 而且是不是占用内存也大?不能用多线程

有没有什么二进制或者位操作之类的奇技淫巧 来瞬间处理这个数组

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

谷夏 2022-09-19 02:23:04
  1. 预先确定目标数组的长度,楼上的代码如果 x = new Array(150000);的话,时间可能会减小到 5ms 以下;
  2. 采用循环展开,一次读取多个数据,类似于这样写:

    const MAX = 150000;
    const gen = () => (0|(Math.random()*100)),
        a = new Array(MAX);
    let max = MAX;
    while(max--){
        a[max] = gen();
    }
    
    // 上面只是准备,以下才是迭代运算
    const res = new Array(MAX);
    // 每个周期读出多个数,有效减少时间复杂度
    for(let cnt = 0; cnt < MAX; cnt += 10){
        res[cnt] = a[cnt] - 7;
        res[cnt + 1] = a[cnt + 1] - 7;
        res[cnt + 2] = a[cnt + 2] - 7;
        // ···以此类推
        res[cnt + 9] = a[cnt + 9] - 7;
    }
  3. 查表,也就是缓存计算结果,这样可以减少运算,应用范围仅限于 被减数取值范围远小于数组长度 的情形,适用于长期运行的项目;
  4. 使用 asmjs,类型标注可以加快执行,配合二进制预先求出 7 的补码将减法转为加法运算来加速,不过由于现代浏览器会采用类似分支预测的方式执行迭代,JS 进行纯数值的大规模迭代运算不会比 asm 慢太多;
  5. 使用 WASM,比asm快,不过由于通信开销大(每个数据复制一遍,除非浏览器已经引入/恢复 SharedArrayBuffer),可能毫无优势,除非数据绝大部分生命周期都在 WASM里面。
红ご颜醉 2022-09-19 02:23:04

手写 150000 行代码,就可以有效避免使用循环,我太机智了

披肩女神 2022-09-19 02:23:04

单纯的for循环,15万,约10毫秒,这速度还可以接受啊!稍微优化下,还能快一丢丢。
image.png

image.png

嗳卜坏 2022-09-19 02:23:04

突然想起之前看到的达夫设备可以优化循环,你可以试试

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文