emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: What's missing in ELisp that makes people want to use cl-lib?


From: João Távora
Subject: Re: What's missing in ELisp that makes people want to use cl-lib?
Date: Thu, 16 Nov 2023 00:28:11 +0000

On Wed, Nov 15, 2023 at 9:21 PM Augusto Stoffel <arstoffel@gmail.com> wrote:
>
> On Wed, 15 Nov 2023 at 14:51, João Távora wrote:
>
> > That and the fact they aren't aware they're anywhere from 5x to
> > 10x slower, sometimes more (I measured 18x for decently realistic),
> > than what they could be.
>
> seq can surely be optimized, and I'm skeptical the issue lies in the
> generic method dispatch (which would be a fundamental problem).  It
> seems more likely due to the fact that the default implementations wrap
> predicate functions and macro bodies into lambdas.
>
> I tried one of the your benchmarks, with results consistent with yours:
>
>   (setq cc (all-completions "" obarray))
>   (setq list2 (make-list 12 "shooveedoowaa"))
>
>   (when nil
>      (benchmark-run 100 (cl-set-difference cc list2 :test #'equal))
>      ;(11.517403284999999 45 4.082223424999995)
>
>      (benchmark-run 100 (seq-difference cc list2))
>      ;(18.507667340999998 119 10.999239876000019)
>      )
>
> Then I tried the first optimization that comes to mind, which is to
> redefine seq-doseq as
>
>   (defmacro seq-doseq (spec &rest body)
>     "Loop over a SEQUENCE, evaluating BODY with VAR bound to each of its 
> elements.
>
>   Similar to `dolist' but can be applied to lists, strings, and vectors.
>
>   \(fn (VAR SEQUENCE) BODY...)"
>     (declare (indent 1) (debug ((symbolp form &optional form) body)))
>     `(let ((var1234 ,(cadr spec)))
>        (cond
>         ((listp var1234)
>          (dolist ,spec ,@body))

I don't think you just skip the seq-do generic like that :-) That breaks
any sequence type based on lists.  This is exactly the problem I
was raising with too-many-generic interfaces, btw.

Try Dmitry's patch instead, the one containing seq-difference-3.  That's
more consequential (but still not fully consequential, though,
also breaks things).

> And now I get:
>
>   (when nil
>      (benchmark-run 100 (cl-set-difference cc list2 :test #'equal))
>      ;(11.517403284999999 45 4.082223424999995)
>
>      (benchmark-run 100 (seq-difference cc list2))
>      ;(7.308574982 29 2.6960850209999876)
>      )

Did you try my feature/cl-lib-improvements branch?
Give cl-nset-difference a try there.

> > Also the fact they don't know cl-seq.el provides all that with
> > a much more versatile interface, and frequently much better
> > performance.

> I for one like the simple aesthetics of seq.

Are you familiar with the cl-lib.el "aesthetics"?
The simple versions argumentless versions are no uglier than seq's,

cl-some vs seq-some
cl-every vs set-every-p
cl-set-difference vs seq-intersection

What specific thing do you like in seq.el that you don't
find in the sequence functions of cl-lib.el?

João



reply via email to

[Prev in Thread] Current Thread [Next in Thread]