V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
bthulu
V2EX  ›  JavaScript

数组多次 filter, 多次 map 混合链式调用过程中, 有没有办法只在最后一次调用时生成一次数组呢?

  •  
  •   bthulu · 2022-07-25 23:48:58 +08:00 · 3351 次点击
    这是一个创建于 837 天前的主题,其中的信息可能已经有所发展或是发生改变。

    貌似每次 filter 或 map 都会返回一个新的数组, 对性能和内存 GC 影响很大. 不知有没有类似 Java 的 Lambda, C#的 Linq, 不论链式调用了多少次 filter, map, select, 都不会生成最终的数组或链表, 而是将这些条件判断函数 /方法存储起来, 直到遇到最后的终结点时, 才进行遍历, 依次匹配前面保存的条件判断, 最终返回一个数组或链表.

    25 条回复    2022-07-26 17:31:54 +08:00
    SoloCompany
        2
    SoloCompany  
       2022-07-26 00:20:04 +08:00 via iPad
    dcsuibian
        3
    dcsuibian  
       2022-07-26 00:21:13 +08:00
    用 for 循环写
    开玩笑的,都用上 js 这种高级语言了,正常使用不需要在乎这点性能,又不是刷算法题。
    hundandadi
        4
    hundandadi  
       2022-07-26 00:41:07 +08:00 via Android
    @dcsuibian 养成个好习惯还是有用的,前几天枚举类型 values 循环 filter 匹配的写法,线上 CPU 升高 10%,定位问题定位了两天才找出来,压测过不了很难受,所以能注意还是注意的好
    Leviathann
        5
    Leviathann  
       2022-07-26 00:47:07 +08:00
    最常用就 lodash 的 chain 咯
    autoxbc
        6
    autoxbc  
       2022-07-26 02:16:57 +08:00
    建议不要在乎性能,除非真的遇到性能问题,然后用单次 forEach 解决。至于 lodash ,使用这个东西,写出来的都不像 JS ,感觉就是完全不同的另一门语言
    isBitter
        7
    isBitter  
       2022-07-26 04:35:40 +08:00
    如果你的 filter map 传入的函数都是纯函数的话,可以把函数 compose 一遍,在调用。
    Magentaize
        8
    Magentaize  
       2022-07-26 07:40:18 +08:00 via iPhone
    RxJS ,就是你想要的
    masterclock
        9
    masterclock  
       2022-07-26 08:55:43 +08:00   ❤️ 1
    除非代码不能用了,否则绝不优化
    即使不能用了,先想想能不能升级硬件

    过早优化乃万恶之源
    bthulu
        10
    bthulu  
    OP
       2022-07-26 08:56:54 +08:00
    @masterclock 无法升级硬件, 部署到客户那边的, 客户随时可能拎出来一台 2000 年的奔腾机器给你
    echo1937
        11
    echo1937  
       2022-07-26 08:58:58 +08:00
    原来这个部分 JS 是没有惰性求值的,学习了。
    musi
        12
    musi  
       2022-07-26 09:01:52 +08:00
    你要不手写 for 循环吧
    ChefIsAwesome
        13
    ChefIsAwesome  
       2022-07-26 09:03:03 +08:00
    不是搞个 lazy 就能神奇的帮你优化的。这种工具库好多,你自己找个,测测耗时吧。
    bojackhorseman
        14
    bojackhorseman  
       2022-07-26 09:40:14 +08:00
    你要不手写 for 循环
    mxT52CRuqR6o5
        15
    mxT52CRuqR6o5  
       2022-07-26 09:41:49 +08:00 via Android
    是你真的碰到了性能问题还是你单纯的觉得这么写不好?
    Lodash 有个 chain 可以惰性求值不知道有多大优化
    你也可以手动 flatMap 把多次遍历合并成一次
    lin07hui
        16
    lin07hui  
       2022-07-26 10:52:03 +08:00
    @bthulu #10 2000 年的奔腾机器能用上现代浏览器吗?用 IE ?
    lmshl
        17
    lmshl  
       2022-07-26 10:53:31 +08:00
    我的 Scala 应用基本上都是每次链式调用求值一次列表,也没比别人 Java 少快几倍。

    而且 JS 有 VM + GC ,除非你跑过 perf 确认这里有性能瓶颈,不然我建议你不要瞎优化,可能适得其反。因为 Lazy evaluation 也是有 overhead 的,数据量小了不如立即求值。

    如果数据量真的大到有必要实施 lazy evaluation 的程度,那我也建议一步到位 RxJS
    ryougifujino
        18
    ryougifujino  
       2022-07-26 11:20:17 +08:00
    Rust 的话就会对这种情况优化,测出来甚至比直接 for 循环更快。
    hronro
        19
    hronro  
       2022-07-26 11:25:19 +08:00
    lazy.js 可以做到,不过这个库好久没维护了。

    https://github.com/dtao/lazy.js
    rrfeng
        20
    rrfeng  
       2022-07-26 12:08:03 +08:00 via Android
    超过三次我宁愿 for 写一遍,看起来更清晰。
    honhon
        21
    honhon  
       2022-07-26 14:01:38 +08:00
    你要不手写 for 循环吧
    molika
        22
    molika  
       2022-07-26 14:20:25 +08:00
    transducer
    bthulu
        23
    bthulu  
    OP
       2022-07-26 14:30:56 +08:00
    @lin07hui 用浏览器干嘛? 我这是跑后台服务, 控制厂内设备自动寻路的
    bthulu
        24
    bthulu  
    OP
       2022-07-26 14:33:29 +08:00
    @honhon 没法手写, 是个公共基类, 会不断有继承类对这个上层数组进行过滤处理. 基类是没法预知所有子类行为的
    frisktale
        25
    frisktale  
       2022-07-26 17:31:54 +08:00
    应该不行吧,又不是 linq
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2781 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 02:00 · PVG 10:00 · LAX 18:00 · JFK 21:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.