help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: looking-at-p slower than looking-at


From: Nicolas Richard
Subject: Re: looking-at-p slower than looking-at
Date: Thu, 26 Nov 2015 14:37:32 +0100
User-agent: mu4e 0.9.15; emacs 25.1.50.1

Hi Marcin,

Marcin Borkowski writes:
> On 2015-11-25, at 14:58, Nicolas Richard <nrichard@ulb.ac.be> wrote:
>
>> Marcin Borkowski <mbork@mbork.pl> writes:
>>
>>> You might also (depending on your use-case) want to use looking-at-p,
>>> which is marginally slower than looking-at, but does not modify match
>>> data.
>>
>> Why is it slower and how much slower is it ? I don't see how it can
>> happen from its implementation:
>>
>> (defsubst looking-at-p (regexp)
>>   "\
>> Same as `looking-at' except this function does not change the match data."
>>   (let ((inhibit-changing-match-data t))
>>     (looking-at regexp)))
>
> One more function call and one more variable binding.  IMHO it /must/ be
> slower, though I think the effect is negligible.

I think there's not more function calls (in compiled code) since
looking-at-p is a defsubst (i.e. gets inlined by the byte compiler). My
own gut feeling is that setting inhibit-changing-match-data allows
`looking-at' to take shortcuts, thus making it actually faster.

> (setq foo "foo")
> (benchmark 10000000 (looking-at foo))
> (benchmark 10000000 (looking-at-p foo))

benchmark is a function, so (looking-at(-p) foo) is evaluated first,
returns nil, and that is what is given to benchmark as argument. IOW
it's not benchmarking anything. You need to quote the form or use
benchmark-run (or use M-x benchmark interactively).

You could also use benchmark-run or benchmark-run-compiled instead (they
are macros). I admit that it's not 100% clear from the docstring that
the situation is different, since they both name call their argument
FORM(S). Perhaps the macros have an argument named "BODY" instead of
"FORMS".

> (AFAIU, it is of utmost importance that you don't use literal stringso
> in such a test, since then it is much more probable that GC will kick
> in. Am I right?)

I think the string litterals are read and "consed" only once. I'll try
to convince you :

(benchmark 3 '(message "%c" (incf (aref "a" 0))))
Running this with C-x C-e, I get :
b
c
d
in my *Message* buffer.

Explanation : when you hit C-x C-e, emacs reads the sexp,
thus translating it in a list of symbols, numbers and strings. At this
point, "a" is thus a string in emacs memory. When the code is run, it
modifies "a" inplace : (incf (aref "a" 0)) returns ?b (which is what we
get in *Messages*) but modifies the string by side effect. So on the
second run, the code gets the same string, which is now "b". Similarly
for the third run, where the string is now "c".

It would have been different had I done :
    (benchmark 3 '(message "%c" (incf (aref (string ?a) 0))))
because now the string "a" is re-constructed at run time everytime.

Conclusion : I don't think you need to avoid string litterals to have
less GC.

Nicolas.



reply via email to

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