cl-lib dash seq的性能对比

https://kisaragi-hiu.com/performance-cl-lib-dash-seq.html

感觉是不是无脑用cl-lib就好了? dash和seq有什么Killer feature么?

有人又说不要使用cl-lib。。。

1 个赞

无脑用 cl-lib 就好了。

dash 那些的API真的看不懂, 炫语法糖

--filter-filter 分数出乎我的意料。把 macro 用函数包裹一下竟然有这么大的提升:

(defun -filter (pred list)
  "Return a new list of the items in LIST for which PRED returns non-nil.

Alias: `-select'.

This function's anaphoric counterpart is `--filter'.

For similar operations, see also `-keep' and `-remove'."
  (--filter (funcall pred it) list))

不过在我电脑上没有100倍那么夸张:

(let ((lst (make-list 100000 8)))
  (k/benchmark-run 100
    (cl-remove-if-not #'cl-oddp lst)
    (-filter #'cl-oddp lst)
    (--filter (cl-oddp it) lst)
    (seq-filter #'cl-oddp lst)))
;; =>
;; ((form\# total gc-count gc-time)
;;  hline
;;  (1 1.8957570000000001  0 0.0)
;;  (2 1.209438            0 0.0)
;;  (3 16.979285           34 7.517744999999991)
;;  (4 6.084852            17 4.153931))
;; =>
;; ((form\# total gc-count gc-time)
;;  hline
;;  (1 1.980998            0 0.0)
;;  (2 1.1938360000000001  0 0.0)
;;  (3 17.657549           34 7.803821000000028)
;;  (4 6.101184            17 4.10154))

因为没用函数包裹相当于每次运行都要宏展开一遍(甚至很有可能你用的 -filter 还是已经 byte compile 过的,而宏生成的是没编译过的代码。

想要“公平”都是 byte compile 以后再 benchmark 的。这博主就是 lisp 水平不够还想搞个大新闻的。

我现在手上没电脑,有请 @cireu 演示一下正确的 benchmark 方法。

dash很多api是从clojure借鉴过来的

很多时候自己的代码貌似不会compile还是有点区别,如果是库应该没影响

应该是这个吧,其实最初的代码是 @xuchunyang 做的

1 个赞

我觉得是 cl-lib 的列表函数太多 keyword 了,不如 seq.el 和 dash 的直观。所以有人觉得不要用 cl-lib,并不是说 cl-lib 性能有问题

比如列表

'((1 . alice)
  (2 . bob)
  (3 . cat)
  (4 . dog))

移除所有单数序号的 pair,用 dash 写

(--remove (cl-oddp (car it)) lst)

换成 cl-lib 却可以写

(cl-remove-if #'cl-oddp lst #:key #'car)

更多奇怪用法请自行到 CL 的 Hyperspec 学习…… http://clhs.lisp.se/Body/f_rm_rm.htm

2 个赞

dash 的 api 就是 clojure 和 kotlin remix 一下的感觉,主要是名字什么的和 clojure 比较接近。对于写 clojure 的人来说,dash 上手很容易。