跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 感觉这次写的库能比 js 原生数组方法要快
未分類
22 2 月 2021

感觉这次写的库能比 js 原生数组方法要快

感觉这次写的库能比 js 原生数组方法要快

資深大佬 : hupo0 2

no-stream 似乎比 js 原生数组方法快

正在等待被锤的忐忑心理中。

大佬有話說 (28)

  • 資深大佬 : eason1874

    不太懂。是循环展开的意思吗?话说现在 JS 不是都要编译了吗,这个在编译时不会自动优化吗?

  • 主 資深大佬 : hupo0

    @eason1874 应该不叫循环展开,是把多次循环合成一个。只见过 c++ 和 rust 有这类优化,而且对代码有不少限制,可能高级语言要考虑闭包什么的。

  • 資深大佬 : cyberpoint

    比如程序员为了方便快捷就会写这种代码:const foo = bar.filter(…).map(…).reduce(…)
    这样就会有 3 次遍历,但是其实这些…的过程是可以在一次遍历中完成的

  • 資深大佬 : muzuiget

    明明就是写法问题,这种 […xxx].map(xxx).filter(xxx).slice(xxx) 我为什么不直接用 for,也是一次循环。

  • 資深大佬 : kkocdko

    是这样的,我记得 rust 的迭代器有这种优化

  • 主 資深大佬 : hupo0

    @cyberpoint 表达到位

  • 資深大佬 : Jirajine

    这个应该不是语言的优化吧,只要方法实现上不返回另一个数组,而是返回一个 lazy evaluation 的 iterator 就可以链式调用多次只遍历一次了。

  • 資深大佬 : muzuiget

    谁白了这种链式求值,就是方便而已,不在乎这点性能损失,真遇到巨大数组,就应该专门写优化代码。

  • 資深大佬 : supermao

    这种不需要猜,你自己做个 benchmark 不就出来了?

  • 資深大佬 : supermao

    @supermao 原来已经做了。。。

  • 資深大佬 : Rorysky

    @muzuiget 这不就是 java stream 的写法么

  • 主 資深大佬 : hupo0

    @Jirajine iterator 转成另一个 iterator,一般是包多一层,该做的“结束检查”还是不会漏的,还是会有额外的性能损耗。实际用 benchmark 测也会发现比较慢。

  • 資深大佬 : jones2000

    太高深了, 看不懂, 学了 2 年 js, 只会用 for(var i=0;i<data.length;++i) …….

  • 資深大佬 : musi

    纠正一下,这不叫比“ js 原生数组方法要快”
    js 可没让你本来遍历一次的事用三次遍历完成

  • 資深大佬 : geelaw

    这个问题和数组遍历几遍没关系,主要区别在于内存分配。

    Array.map 每次都要分配新的数组,可以想象 no-stream 的 map 只是变换迭代器,当然快。当然这不能怪 Array,毕竟功能不同,要写出值得比较的代码可以对 mf 复合自己 map_count 次,再变换成 reducer,然后直接在 data 数组上用 reduce 。

    而且好好写 for 循环不香吗?

  • 資深大佬 : kuunnnn

    这不就是延迟计算吗,lazy.js 有做这个的,lodash 好像也有类似的

  • 資深大佬 : shyangs

    為什麼不用 lodash 的_.chain()

  • 資深大佬 : molika

    transduce 而已 clojure/clojureScript N 年前就这么玩了 话说 js 的 map reduce 啥的竟然不是惰性的 transduce ? 吃惊

  • 主 資深大佬 : hupo0

    @shyangs lodash 没用过,我才知道 chain 。看了下源码,他用一个 Wrapper 的抽象,在求值前,把中间的 actions 合成一个。虽然感觉大家想做的事情一样,但实现上效率不那么高。不过 lodash 自带的东西多,容错好,本身不用太注重效率。

    实际 benchmark 跑下来,速度和数组自带的方法差不多,但是内存上应该会更优越。

  • 主 資深大佬 : hupo0

    @geelaw 比较的代码确实有的斟酌的地方,但是太难找到合适的,就粗暴点只比较了 map 和 reduce 一起用的情况。

    就是不想好好写 for 循环。

  • 主 資深大佬 : hupo0

    @musi 所以用了似乎,实际上,如果要提高代码的表达,很多时候不会选择把逻辑都挤在一个循环里,至少我是这样的。

  • 資深大佬 : civet

    @molika js 不是天生就是为函数式编程服务的,而是社区各路大神引领了这种潮流,实际上就是底层没实现,写法先出现

  • 資深大佬 : Rocketer

    js 聊性能的意义不是特别大,毕竟主要用途是前端,数组大小不会超过 100 条。相比较而言,节约代码提高开发效率更受欢迎。

    真要用在后端处理大数据,那还是像 Python 那样用 C 做类库,让 js 调用吧,纯 js 再努力也提升不了太多

  • 資深大佬 : darknoll

    没有意义,前端无需注重效率,数据量大了应该是分页之类的,反正 Iterable 对象我都用 for of,我也知道 for 循环速度最快。

  • 資深大佬 : wxsm

    从算法角度来说,1 次循环,3 次循环,n 次循环,时间复杂度都是 O(n),并没有实质区别。

  • 資深大佬 : cenbiq

    不禁感慨,C#的 Linq 真是有远见

  • 主 資深大佬 : hupo0

    @cenbiq 看看所谓的 Zero cost abstraction – 刘雨培的文章 – 知乎
    https://zhuanlan.zhihu.com/p/24975048
    吐槽 C# – 刘雨培的文章 – 知乎
    https://zhuanlan.zhihu.com/p/30653282

    参考这两篇回答,17 年的 C#还没有对 linq 进行优化。虽然用迭代器也是相当于只遍历一遍,但是迭代器“调用”迭代器的过程还是会有额外的性能损耗。完美一点的是,能做到跟 C++一样,把迭代器 yield 的逻辑内联到一个循环里。

    想来 no-stream 的做法,是函数调用层面,把”yield”部分通过函数包函数的方式合并到一个循环里。虽然也是有函数调用方面的开销,但目前来看,会比 JS 的 Generator 还节省性能些。

    从现有的 C++和 Rust 的案例来看,其实正道还是 iterator,似乎这样的结构更容易优化。linq 也是在正道上,只是需要引擎对这部分进行优化。与之对应的是 JS 的 Generator 。可惜就是目前他们还很拉胯。

  • 資深大佬 : cenbiq

    @hupo0 用 yield 肯定会产生额外性能损耗嘛。js 是有 Generator 但是我接触下来应用很少,反观 C# IEnumerable 和 IEnumerator 几乎是必不可少的东西,no-stream 类似 rx 管道吧,收集操作最后一次循环执行,无非就是这些方法了。
    不过还是得夸 linq,想当初换到 js 和 java 各种不习惯。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具