* How to count the number of occurrences of a character in a string?
@ 2015-10-12 19:45 Marcin Borkowski
2015-10-12 21:43 ` Kaushal Modi
2015-10-13 22:00 ` Emanuel Berg
0 siblings, 2 replies; 24+ messages in thread
From: Marcin Borkowski @ 2015-10-12 19:45 UTC (permalink / raw)
To: Help Gnu Emacs mailing list
Hi all,
the subject line says it all. Is there any built-in Elisp function to
do that? Should I just use cl-count?
Best,
--
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-12 19:45 How to count the number of occurrences of a character in a string? Marcin Borkowski
@ 2015-10-12 21:43 ` Kaushal Modi
2015-10-12 23:27 ` Nick Dokos
2015-10-13 1:18 ` Stefan Monnier
2015-10-13 22:00 ` Emanuel Berg
1 sibling, 2 replies; 24+ messages in thread
From: Kaushal Modi @ 2015-10-12 21:43 UTC (permalink / raw)
To: Marcin Borkowski, Help Gnu Emacs mailing list
I took it up as an elisp exercise and got the below (not sure if it is
performance optimal for your application):
The catch form returns the number of matches.
(let ((char ?a)
(str "abcda"))
(catch 'break
(let* ((str str)
(len (length str))
(num-matches 0)
match-pos)
(dotimes (i len)
(setq match-pos (string-match-p (char-to-string char) str))
(when match-pos
(setq str (substring-no-properties str (1+ match-pos)))
(setq len (length str))
(setq num-matches (1+ num-matches)))
(when (= 0 len)
(throw 'break num-matches))))))
Below is the same code as above with some debug statements:
(let ((char ?a)
(str "abcda"))
(message "%0d occurrences of `%c' char found in \"%s\""
(catch 'break
(let* ((str str)
(len (length str))
(num-matches 0)
match-pos)
(dotimes (i len)
(message "i = %0d str = %0s" i str)
(setq match-pos (string-match-p (char-to-string char) str))
(when match-pos
(message "match-pos = %0d str = %0s" match-pos str)
(setq str (substring-no-properties str (1+ match-pos)))
(message "new str = %0s" str)
(setq len (length str))
(setq num-matches (1+ num-matches)))
(when (= 0 len)
(throw 'break num-matches)))))
char str))
On Mon, Oct 12, 2015 at 3:45 PM Marcin Borkowski <mbork@mbork.pl> wrote:
> Hi all,
>
> the subject line says it all. Is there any built-in Elisp function to
> do that? Should I just use cl-count?
>
> Best,
>
> --
> Marcin Borkowski
> http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
> Faculty of Mathematics and Computer Science
> Adam Mickiewicz University
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-12 21:43 ` Kaushal Modi
@ 2015-10-12 23:27 ` Nick Dokos
2015-10-13 1:18 ` Stefan Monnier
1 sibling, 0 replies; 24+ messages in thread
From: Nick Dokos @ 2015-10-12 23:27 UTC (permalink / raw)
To: help-gnu-emacs
Kaushal Modi <kaushal.modi@gmail.com> writes:
> I took it up as an elisp exercise and got the below (not sure if it is
> performance optimal for your application):
>
> The catch form returns the number of matches.
>
> (let ((char ?a)
> (str "abcda"))
> (catch 'break
> (let* ((str str)
> (len (length str))
> (num-matches 0)
> match-pos)
> (dotimes (i len)
> (setq match-pos (string-match-p (char-to-string char) str))
> (when match-pos
> (setq str (substring-no-properties str (1+ match-pos)))
> (setq len (length str))
> (setq num-matches (1+ num-matches)))
> (when (= 0 len)
> (throw 'break num-matches))))))
>
What happens if len never becomes 0 in the loop? E.g looking for "f" in
"falala" or "alala"? No throw, so catch returns nil: you probably want
to add another throw outside the loop; or (better) do something else
when match-pos is nil (there are no more matches), so you don't go
through the loop uselessly:
(if match-pos
(progn
(setq str ...)
(setq len ...)
(setq nm-matches))
(throw 'break num-matches))
But I suspect cl-count will be much faster.
Nick
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
[not found] <mailman.164.1444679125.7904.help-gnu-emacs@gnu.org>
@ 2015-10-12 23:35 ` Joost Kremers
0 siblings, 0 replies; 24+ messages in thread
From: Joost Kremers @ 2015-10-12 23:35 UTC (permalink / raw)
To: help-gnu-emacs
Marcin Borkowski wrote:
> the subject line says it all. Is there any built-in Elisp function to
> do that?
Not that I know of.
> Should I just use cl-count?
That's one option, if you don't mind depending on cl.
Alternatively, split-string may be of help:
(length (split-string "abcbdbeb" "[^b]" t)) ==> 4 (#o4, #x4, ?\C-d)
But that's rather opaque, so you might want to add a comment to tell
your future self what you're doing here...
--
Joost Kremers joostkremers@fastmail.fm
Selbst in die Unterwelt dringt durch Spalten Licht
EN:SiS(9)
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-12 21:43 ` Kaushal Modi
2015-10-12 23:27 ` Nick Dokos
@ 2015-10-13 1:18 ` Stefan Monnier
2015-10-13 16:06 ` Kaushal Modi
1 sibling, 1 reply; 24+ messages in thread
From: Stefan Monnier @ 2015-10-13 1:18 UTC (permalink / raw)
To: help-gnu-emacs
> (setq str (substring-no-properties str (1+ match-pos)))
This will give wrong results for regexp that use things like ^ and \`.
Instead, you should keep using the same `str' and instead pass the
`start' arg to string-match.
Stefan
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 1:18 ` Stefan Monnier
@ 2015-10-13 16:06 ` Kaushal Modi
2015-10-13 16:31 ` Kaushal Modi
2015-10-13 16:48 ` Eli Zaretskii
0 siblings, 2 replies; 24+ messages in thread
From: Kaushal Modi @ 2015-10-13 16:06 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Help Gnu Emacs mailing list
Thanks Nick, Stefan for the feedback.
Here's the updated code just to fix the issues you pointed out (with a
little "test-suite" at the end of that progn form) :
(progn
(defun my/count-char-in-string (char str)
"Count the number of times CHAR character appears in STR string."
(message "\n==========\nstr = %0s" str)
(let* ((num-matches 0)
(ptr 0) ; initiate pointer for string match
match-pos)
(while (<= ptr (length str))
(message "ptr = %0d" ptr)
(setq match-pos (string-match-p
(regexp-quote (char-to-string char)) str ptr))
(if match-pos
(progn
(setq ptr (1+ match-pos))
(message "match-pos = %0d ptr = %0d" match-pos ptr)
(setq num-matches (1+ num-matches)))
(progn
(setq ptr (1+ ptr)))))
(message "%0d occurrence%0s of `%c' char found in \"%s\"."
num-matches (if (/= 1 num-matches) "s" "") char str)
num-matches))
(my/count-char-in-string ?a "abcda")
(my/count-char-in-string ?z "abcda")
(my/count-char-in-string ?f "falalala")
(my/count-char-in-string ?^ "f^la^lala^dabra^^")
(my/count-char-in-string ?\\ "\\falalala\\"))
--
Kaushal Modi
On Mon, Oct 12, 2015 at 9:18 PM, Stefan Monnier
<monnier@iro.umontreal.ca> wrote:
>> (setq str (substring-no-properties str (1+ match-pos)))
>
> This will give wrong results for regexp that use things like ^ and \`.
>
> Instead, you should keep using the same `str' and instead pass the
> `start' arg to string-match.
>
>
> Stefan
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 16:06 ` Kaushal Modi
@ 2015-10-13 16:31 ` Kaushal Modi
2015-10-13 16:48 ` Eli Zaretskii
1 sibling, 0 replies; 24+ messages in thread
From: Kaushal Modi @ 2015-10-13 16:31 UTC (permalink / raw)
Cc: Help Gnu Emacs mailing list
Sorry, I don't intend to keep on spamming this thread. But I made a
dumb mistake in the previous code.
Below is fixed. The while loop now stops as soon as match-pos is nil;
there was no need to crawl through the whole string.
(progn
(defun my/count-char-in-string (char str)
"Count the number of times CHAR character appears in STR string."
(message "\n==========\nstr = %0s" str)
(let* ((num-matches 0)
(ptr 0) ; initiate pointer for string match
match-pos)
(while (<= ptr (length str))
(message "ptr = %0d" ptr)
(setq match-pos (string-match-p
(regexp-quote (char-to-string char)) str ptr))
(if match-pos
(progn
(setq ptr (1+ match-pos))
(message "match-pos = %0d ptr = %0d" match-pos ptr)
(setq num-matches (1+ num-matches)))
(progn
(setq ptr (1+ (length str))))))
(message "%0d occurrence%0s of `%c' char found in \"%s\"."
num-matches (if (/= 1 num-matches) "s" "") char str)
num-matches))
(my/count-char-in-string ?a "abcda")
(my/count-char-in-string ?z "abcda")
(my/count-char-in-string ?f "falalala")
(my/count-char-in-string ?l "falalalaabcds")
(my/count-char-in-string ?^ "f^la^lala^dabra^^")
(my/count-char-in-string ?\\ "\\falalala\\"))
--
Kaushal Modi
On Tue, Oct 13, 2015 at 12:06 PM, Kaushal Modi <kaushal.modi@gmail.com> wrote:
> Thanks Nick, Stefan for the feedback.
>
> Here's the updated code just to fix the issues you pointed out (with a
> little "test-suite" at the end of that progn form) :
>
> (progn
> (defun my/count-char-in-string (char str)
> "Count the number of times CHAR character appears in STR string."
> (message "\n==========\nstr = %0s" str)
> (let* ((num-matches 0)
> (ptr 0) ; initiate pointer for string match
> match-pos)
> (while (<= ptr (length str))
> (message "ptr = %0d" ptr)
> (setq match-pos (string-match-p
> (regexp-quote (char-to-string char)) str ptr))
> (if match-pos
> (progn
> (setq ptr (1+ match-pos))
> (message "match-pos = %0d ptr = %0d" match-pos ptr)
> (setq num-matches (1+ num-matches)))
> (progn
> (setq ptr (1+ ptr)))))
> (message "%0d occurrence%0s of `%c' char found in \"%s\"."
> num-matches (if (/= 1 num-matches) "s" "") char str)
> num-matches))
> (my/count-char-in-string ?a "abcda")
> (my/count-char-in-string ?z "abcda")
> (my/count-char-in-string ?f "falalala")
> (my/count-char-in-string ?^ "f^la^lala^dabra^^")
> (my/count-char-in-string ?\\ "\\falalala\\"))
>
> --
> Kaushal Modi
>
>
> On Mon, Oct 12, 2015 at 9:18 PM, Stefan Monnier
> <monnier@iro.umontreal.ca> wrote:
>>> (setq str (substring-no-properties str (1+ match-pos)))
>>
>> This will give wrong results for regexp that use things like ^ and \`.
>>
>> Instead, you should keep using the same `str' and instead pass the
>> `start' arg to string-match.
>>
>>
>> Stefan
>>
>>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 16:06 ` Kaushal Modi
2015-10-13 16:31 ` Kaushal Modi
@ 2015-10-13 16:48 ` Eli Zaretskii
2015-10-13 17:41 ` Eli Zaretskii
2015-10-13 17:43 ` Kaushal Modi
1 sibling, 2 replies; 24+ messages in thread
From: Eli Zaretskii @ 2015-10-13 16:48 UTC (permalink / raw)
To: help-gnu-emacs
> From: Kaushal Modi <kaushal.modi@gmail.com>
> Date: Tue, 13 Oct 2015 12:06:36 -0400
> Cc: Help Gnu Emacs mailing list <help-gnu-emacs@gnu.org>
>
> (progn
> (defun my/count-char-in-string (char str)
> "Count the number of times CHAR character appears in STR string."
> (message "\n==========\nstr = %0s" str)
> (let* ((num-matches 0)
> (ptr 0) ; initiate pointer for string match
> match-pos)
> (while (<= ptr (length str))
> (message "ptr = %0d" ptr)
> (setq match-pos (string-match-p
> (regexp-quote (char-to-string char)) str ptr))
> (if match-pos
> (progn
> (setq ptr (1+ match-pos))
> (message "match-pos = %0d ptr = %0d" match-pos ptr)
> (setq num-matches (1+ num-matches)))
> (progn
> (setq ptr (1+ ptr)))))
> (message "%0d occurrence%0s of `%c' char found in \"%s\"."
> num-matches (if (/= 1 num-matches) "s" "") char str)
> num-matches))
Isn't the following simpler?
(let ((str-list (append str nil))
(num-matches 0))
(while str-list
(if (= (car str-list) char)
(setq num-matches (1+ num-matches)))
(setq str-list (cdr str-list)))
num-matches)
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 16:48 ` Eli Zaretskii
@ 2015-10-13 17:41 ` Eli Zaretskii
2015-10-13 17:43 ` Kaushal Modi
1 sibling, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2015-10-13 17:41 UTC (permalink / raw)
To: help-gnu-emacs
> Date: Tue, 13 Oct 2015 19:48:15 +0300
> From: Eli Zaretskii <eliz@gnu.org>
>
> Isn't the following simpler?
>
> (let ((str-list (append str nil))
> (num-matches 0))
> (while str-list
> (if (= (car str-list) char)
> (setq num-matches (1+ num-matches)))
> (setq str-list (cdr str-list)))
> num-matches)
Which could be made even more elegant (and faster, I guess) by using
'mapc', of course.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 16:48 ` Eli Zaretskii
2015-10-13 17:41 ` Eli Zaretskii
@ 2015-10-13 17:43 ` Kaushal Modi
2015-10-13 19:07 ` Eli Zaretskii
` (2 more replies)
1 sibling, 3 replies; 24+ messages in thread
From: Kaushal Modi @ 2015-10-13 17:43 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Help Gnu Emacs mailing list
Thanks Eli. That's neat! I was over-engineering :)
I am, though, unable to quantify which approach is the fastest using
`benchmark`.
I ran the below wrapper progn block couple of times and I got
different results each time. Oddly enough, I even got negative
execution times.
What am I doing wrong?
RESULT:
100000 executions of string-match-p approach:
Elapsed time: 0.000330s
100000 executions of cl-count approach:
Elapsed time: 0.000357s
100000 executions of cdr approach:
Elapsed time: -0.000378s <<<<<<<<<<<<<<<<<<< negative time??
nil
100000 executions of string-match-p approach:
Elapsed time: 0.001972s
100000 executions of cl-count approach:
Elapsed time: 0.000728s
100000 executions of cdr approach:
Elapsed time: 0.000638s
nil
100000 executions of string-match-p approach:
Elapsed time: -0.000199s <<<<<<<<<<<<<<<<<<< negative time??
100000 executions of cl-count approach:
Elapsed time: 0.000766s
100000 executions of cdr approach:
Elapsed time: 0.001562s
nil
CODE:
(progn
(message "100000 executions of string-match-p approach: ")
(benchmark
100000
(progn
(defun my/count-char-in-string (char str)
"Count the number of times CHAR character appears in STR string."
;; (message "\n==========\nstr = %0s" str)
(let* ((num-matches 0)
(ptr 0) ; initiate pointer for string match
match-pos)
(while (<= ptr (length str))
;; (message "ptr = %0d" ptr)
(setq match-pos (string-match-p
(regexp-quote (char-to-string char)) str ptr))
(if match-pos
(progn
(setq ptr (1+ match-pos))
;; (message "match-pos = %0d ptr = %0d" match-pos ptr)
(setq num-matches (1+ num-matches)))
(progn
(setq ptr (1+ (length str))))))
;; (message "%0d occurrence%0s of `%c' char found in \"%s\"."
;; num-matches (if (/= 1 num-matches) "s" "") char str)
num-matches))
(my/count-char-in-string ?a "abcda")
(my/count-char-in-string ?z "abcda")
(my/count-char-in-string ?f "falalala")
(my/count-char-in-string ?l "falalalaabcds")
(my/count-char-in-string ?^ "f^la^lala^dabra^^")
(my/count-char-in-string ?\\ "\\falalala\\")))
(message "100000 executions of cl-count approach: ")
(benchmark
100000
(progn
(cl-count ?a "abcda")
(cl-count ?z "abcda")
(cl-count ?f "falalala")
(cl-count ?l "falalalaabcds")
(cl-count ?^ "f^la^lala^dabra^^")
(cl-count ?\\ "\\falalala\\")))
(message "100000 executions of cdr approach: ")
(benchmark
100000
(progn
(defun my2/count-char-in-string (char str)
(let ((str-list (append str nil))
(num-matches 0))
(while str-list
(if (= (car str-list) char)
(setq num-matches (1+ num-matches)))
(setq str-list (cdr str-list)))
num-matches))
(my2/count-char-in-string ?a "abcda")
(my2/count-char-in-string ?z "abcda")
(my2/count-char-in-string ?f "falalala")
(my2/count-char-in-string ?l "falalalaabcds")
(my2/count-char-in-string ?^ "f^la^lala^dabra^^")
(my2/count-char-in-string ?\\ "\\falalala\\")))
nil)
--
Kaushal Modi
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 17:43 ` Kaushal Modi
@ 2015-10-13 19:07 ` Eli Zaretskii
2015-10-13 19:56 ` Kaushal Modi
2015-10-13 20:43 ` Michael Heerdegen
2015-10-14 18:19 ` Noam Postavsky
2 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2015-10-13 19:07 UTC (permalink / raw)
To: help-gnu-emacs
> From: Kaushal Modi <kaushal.modi@gmail.com>
> Date: Tue, 13 Oct 2015 13:43:05 -0400
> Cc: Help Gnu Emacs mailing list <help-gnu-emacs@gnu.org>
>
> I am, though, unable to quantify which approach is the fastest using
> `benchmark`.
>
> I ran the below wrapper progn block couple of times and I got
> different results each time. Oddly enough, I even got negative
> execution times.
> What am I doing wrong?
Could be a bug in 'benchmark'. Just call float-time before and after,
and subtract the values, it should be good enough.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 19:07 ` Eli Zaretskii
@ 2015-10-13 19:56 ` Kaushal Modi
2015-10-13 20:17 ` Eli Zaretskii
[not found] ` <mailman.267.1444767491.7904.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 24+ messages in thread
From: Kaushal Modi @ 2015-10-13 19:56 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Help Gnu Emacs mailing list
Thanks!
Now I see some convergence in the results and this was the conclusion,
fastest to slowest
1. cl-count
2. Eli's cdr approach
3. My string-match-p approach
Code: https://gist.github.com/ab487f63727381179f61
Raw results:
1000 executions of string-match-p approach took 0.047036 seconds
1000 executions of cl-count approach took 0.036476 seconds
1000 executions of cdr approach took 0.043735 seconds
nil
1000 executions of string-match-p approach took 0.046918 seconds
1000 executions of cl-count approach took 0.035476 seconds
1000 executions of cdr approach took 0.202394 seconds
nil
1000 executions of string-match-p approach took 0.047496 seconds
1000 executions of cl-count approach took 0.035816 seconds
1000 executions of cdr approach took 0.043535 seconds
nil
1000 executions of string-match-p approach took 0.047068 seconds
1000 executions of cl-count approach took 0.035923 seconds
1000 executions of cdr approach took 0.043363 seconds
nil
1000 executions of string-match-p approach took 0.047406 seconds
1000 executions of cl-count approach took 0.034490 seconds
1000 executions of cdr approach took 0.043718 seconds
nil
1000 executions of string-match-p approach took 0.047117 seconds
1000 executions of cl-count approach took 0.035804 seconds
1000 executions of cdr approach took 0.043340 seconds
nil
1000 executions of string-match-p approach took 0.208332 seconds
1000 executions of cl-count approach took 0.035798 seconds
1000 executions of cdr approach took 0.043902 seconds
nil
1000 executions of string-match-p approach took 0.047357 seconds
1000 executions of cl-count approach took 0.035955 seconds
1000 executions of cdr approach took 0.043331 seconds
nil
--
Kaushal Modi
On Tue, Oct 13, 2015 at 3:07 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>> From: Kaushal Modi <kaushal.modi@gmail.com>
>> Date: Tue, 13 Oct 2015 13:43:05 -0400
>> Cc: Help Gnu Emacs mailing list <help-gnu-emacs@gnu.org>
>>
>> I am, though, unable to quantify which approach is the fastest using
>> `benchmark`.
>>
>> I ran the below wrapper progn block couple of times and I got
>> different results each time. Oddly enough, I even got negative
>> execution times.
>> What am I doing wrong?
>
> Could be a bug in 'benchmark'. Just call float-time before and after,
> and subtract the values, it should be good enough.
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 19:56 ` Kaushal Modi
@ 2015-10-13 20:17 ` Eli Zaretskii
2015-10-13 20:41 ` Kaushal Modi
[not found] ` <mailman.267.1444767491.7904.help-gnu-emacs@gnu.org>
1 sibling, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2015-10-13 20:17 UTC (permalink / raw)
To: help-gnu-emacs
> From: Kaushal Modi <kaushal.modi@gmail.com>
> Date: Tue, 13 Oct 2015 15:56:57 -0400
> Cc: Help Gnu Emacs mailing list <help-gnu-emacs@gnu.org>
>
> Now I see some convergence in the results and this was the conclusion,
> fastest to slowest
>
> 1. cl-count
> 2. Eli's cdr approach
> 3. My string-match-p approach
>
> Code: https://gist.github.com/ab487f63727381179f61
> Raw results:
>
> 1000 executions of string-match-p approach took 0.047036 seconds
> 1000 executions of cl-count approach took 0.036476 seconds
> 1000 executions of cdr approach took 0.043735 seconds
> nil
> 1000 executions of string-match-p approach took 0.046918 seconds
> 1000 executions of cl-count approach took 0.035476 seconds
> 1000 executions of cdr approach took 0.202394 seconds
> nil
Looks like 1000 loops is too few: your measurements hit clock
quantization error, and also some background activities affect the
results. I suggest to try 10000 iterations.
Also, did you actually try 'mapc', per my second suggestion?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 20:17 ` Eli Zaretskii
@ 2015-10-13 20:41 ` Kaushal Modi
0 siblings, 0 replies; 24+ messages in thread
From: Kaushal Modi @ 2015-10-13 20:41 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Help Gnu Emacs mailing list
Just tried that, mapc is the best alternative after cl-count.
Updated the results and code at
https://gist.github.com/kaushalmodi/ab487f63727381179f61
--
Kaushal Modi
On Tue, Oct 13, 2015 at 4:17 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>> From: Kaushal Modi <kaushal.modi@gmail.com>
>> Date: Tue, 13 Oct 2015 15:56:57 -0400
>> Cc: Help Gnu Emacs mailing list <help-gnu-emacs@gnu.org>
>>
>> Now I see some convergence in the results and this was the conclusion,
>> fastest to slowest
>>
>> 1. cl-count
>> 2. Eli's cdr approach
>> 3. My string-match-p approach
>>
>> Code: https://gist.github.com/ab487f63727381179f61
>> Raw results:
>>
>> 1000 executions of string-match-p approach took 0.047036 seconds
>> 1000 executions of cl-count approach took 0.036476 seconds
>> 1000 executions of cdr approach took 0.043735 seconds
>> nil
>> 1000 executions of string-match-p approach took 0.046918 seconds
>> 1000 executions of cl-count approach took 0.035476 seconds
>> 1000 executions of cdr approach took 0.202394 seconds
>> nil
>
> Looks like 1000 loops is too few: your measurements hit clock
> quantization error, and also some background activities affect the
> results. I suggest to try 10000 iterations.
>
> Also, did you actually try 'mapc', per my second suggestion?
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 17:43 ` Kaushal Modi
2015-10-13 19:07 ` Eli Zaretskii
@ 2015-10-13 20:43 ` Michael Heerdegen
2015-10-13 20:59 ` Charles Curley
2015-10-14 18:19 ` Noam Postavsky
2 siblings, 1 reply; 24+ messages in thread
From: Michael Heerdegen @ 2015-10-13 20:43 UTC (permalink / raw)
To: help-gnu-emacs
Kaushal Modi <kaushal.modi@gmail.com> writes:
> 100000 executions of cdr approach:
> Elapsed time: -0.000378s
A great discovery! If we loop that code in the background, it will
massively speed up Emacs.
Michael.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
[not found] ` <mailman.267.1444767491.7904.help-gnu-emacs@gnu.org>
@ 2015-10-13 20:46 ` Brendan Halpin
2015-10-13 21:07 ` Kaushal Modi
[not found] ` <mailman.273.1444770543.7904.help-gnu-emacs@gnu.org>
0 siblings, 2 replies; 24+ messages in thread
From: Brendan Halpin @ 2015-10-13 20:46 UTC (permalink / raw)
To: help-gnu-emacs
On Tue, Oct 13 2015, Eli Zaretskii wrote:
> Also, did you actually try 'mapc', per my second suggestion?
Why not mapcar?
(defun test (str char)
(apply '+ (mapcar (lambda (x) (if (= x char) 1 0))
str)))
B
--
Brendan Halpin, Head, Department of Sociology, University of Limerick, Ireland
Tel: w +353-61-213147 f +353-61-202569 h +353-61-338562; Room F1-002 x 3147
mailto:brendan.halpin@ul.ie ULSociology on Facebook: http://on.fb.me/fjIK9t
http://teaching.sociology.ul.ie/bhalpin/wordpress twitter:@ULSociology
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 20:43 ` Michael Heerdegen
@ 2015-10-13 20:59 ` Charles Curley
0 siblings, 0 replies; 24+ messages in thread
From: Charles Curley @ 2015-10-13 20:59 UTC (permalink / raw)
To: help-gnu-emacs
On Tue, 13 Oct 2015 22:43:02 +0200
Michael Heerdegen <michael_heerdegen@web.de> wrote:
> Kaushal Modi <kaushal.modi@gmail.com> writes:
>
> > 100000 executions of cdr approach:
> > Elapsed time: -0.000378s
>
> A great discovery! If we loop that code in the background, it will
> massively speed up Emacs.
Then they can use Emacs to time neutrinos.
--
The right of the people to be secure in their persons, houses, papers,
and effects, against unreasonable searches and seizures, shall not be
violated, and no Warrants shall issue, but upon probable cause,
supported by Oath or affirmation, and particularly describing the
place to be searched, and the persons or things to be seized.
-- U.S. Const. Amendment IV
Key fingerprint = CE5C 6645 A45A 64E4 94C0 809C FFF6 4C48 4ECD DFDB
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 20:46 ` Brendan Halpin
@ 2015-10-13 21:07 ` Kaushal Modi
[not found] ` <mailman.273.1444770543.7904.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 24+ messages in thread
From: Kaushal Modi @ 2015-10-13 21:07 UTC (permalink / raw)
To: brendan.halpin; +Cc: Help Gnu Emacs mailing list
Looks like mapcar is
now at
the 2nd place by a hair.. mapc drops down to 3rd place
. Updated https://gist.github.com/kaushalmodi/ab487f63727381179f61
;; Fastest to slowest approach;;;;
|------+--------------+-----------------------|;; | Rank | Method | Time in
second |;; | | | for 100000 executions |;; | | | (very rough avg) |;;
|------+--------------+-----------------------|;; | 1 | cl-count | 1.0 to
1.6 |;; | 2 | mapcar | 1.9 to 2.1 |;; | 3 | mapc | 2.0 to 2.6 |;; | 4 | cdr
| 2.4 to 3.3 |;; | 5 | split-string | 4.0 to 4.7 |;; | 5* | string-match |
3.7 to 4.7 |;; |------+--------------+-----------------------|
--
Kaushal Modi
On Tue, Oct 13, 2015 at 4:46 PM, Brendan Halpin <brendan.halpin@ul.ie>
wrote:
> On Tue, Oct 13 2015, Eli Zaretskii wrote:
>
> > Also, did you actually try 'mapc', per my second suggestion?
>
> Why not mapcar?
>
> (defun test (str char)
> (apply '+ (mapcar (lambda (x) (if (= x char) 1 0))
> str)))
>
> B
> --
> Brendan Halpin, Head, Department of Sociology, University of Limerick,
> Ireland
> Tel: w +353-61-213147 f +353-61-202569 h +353-61-338562; Room F1-002 x
> 3147
> mailto:brendan.halpin@ul.ie ULSociology on Facebook:
> http://on.fb.me/fjIK9t
> http://teaching.sociology.ul.ie/bhalpin/wordpress
> twitter:@ULSociology
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-12 19:45 How to count the number of occurrences of a character in a string? Marcin Borkowski
2015-10-12 21:43 ` Kaushal Modi
@ 2015-10-13 22:00 ` Emanuel Berg
1 sibling, 0 replies; 24+ messages in thread
From: Emanuel Berg @ 2015-10-13 22:00 UTC (permalink / raw)
To: help-gnu-emacs
Marcin Borkowski <mbork@mbork.pl> writes:
> Should I ... use cl-count?
Why not?
(defun count-char-in-string (the-char str)
(if (and (char-or-string-p the-char)
(char-or-string-p str) )
(let ((c (if (characterp the-char) the-char (string-to-char the-char))))
(cl-count c (string-to-list str)) )
(error "Indata verification failed.") ))
(count-char-in-string "o" "oooiiiooo") ; 6
(count-char-in-string ?\o "oooiiiooo") ; 6
(count-char-in-string 111 "oooiiiooo") ; 6
(count-char-in-string '(1) "oooiiiooo") ; error
(count-char-in-string "o" '(1)) ; error
--
underground experts united
http://user.it.uu.se/~embe8573
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
[not found] ` <mailman.273.1444770543.7904.help-gnu-emacs@gnu.org>
@ 2015-10-13 22:44 ` Joost Kremers
2015-10-14 10:04 ` Oleh Krehel
0 siblings, 1 reply; 24+ messages in thread
From: Joost Kremers @ 2015-10-13 22:44 UTC (permalink / raw)
To: help-gnu-emacs
Kaushal Modi wrote:
> . Updated https://gist.github.com/kaushalmodi/ab487f63727381179f61
You should byte-compile them. Makes the difference between cl-count and
the rest even bigger.
These are the results from only one run (each function called 100000
times), but I get similar results when I repeat the test:
,----
| cl-count 0.697451
| count-char-in-string-cl-count 0.743856
| count-char-in-string-mapcar 2.196961
| count-char-in-string-mapc 1.817378
| count-char-in-string-cdr 1.669147
| count-char-in-string-string-match 3.815134
`----
(I left out split-string as it produces the wrong result when the char
being counted appears twice in a row.)
The cl-count vs. count-char-in-string-cl-count are a direct call to
cl-count vs. cl-count wrapped in a function. There is obviously some
overhead to the additional function call, but even then cl-count wins
hands down.
Code is here:
https://gist.github.com/joostkremers/0e07a35c85758a2fcb52
--
Joost Kremers joostkremers@fastmail.fm
Selbst in die Unterwelt dringt durch Spalten Licht
EN:SiS(9)
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 22:44 ` Joost Kremers
@ 2015-10-14 10:04 ` Oleh Krehel
2015-10-14 17:06 ` Eli Zaretskii
0 siblings, 1 reply; 24+ messages in thread
From: Oleh Krehel @ 2015-10-14 10:04 UTC (permalink / raw)
To: help-gnu-emacs
Hi Joost,
Joost Kremers <joost.m.kremers@gmail.com> writes:
> You should byte-compile them. Makes the difference between cl-count and
> the rest even bigger.
>
> These are the results from only one run (each function called 100000
> times), but I get similar results when I repeat the test:
>
> ,----
> | cl-count 0.697451
> | count-char-in-string-cl-count 0.743856
> | count-char-in-string-mapcar 2.196961
> | count-char-in-string-mapc 1.817378
> | count-char-in-string-cdr 1.669147
> | count-char-in-string-string-match 3.815134
> `----
>
> (I left out split-string as it produces the wrong result when the char
> being counted appears twice in a row.)
>
> The cl-count vs. count-char-in-string-cl-count are a direct call to
> cl-count vs. cl-count wrapped in a function. There is obviously some
> overhead to the additional function call, but even then cl-count wins
> hands down.
>
> Code is here:
>
> https://gist.github.com/joostkremers/0e07a35c85758a2fcb52
Thanks for the test cases. Here are their results on my machine:
cl-count 0.821659
my-count 0.378911
count-char-in-string-cl-count 0.853604
count-char-in-string-mapcar 1.367351
count-char-in-string-mapc 1.372528
count-char-in-string-cdr 1.123716
count-char-in-string-string-match 2.478769
And here's the code of my-count - it's just cl-count simplified to work
only on strings:
(defun my-count (char str)
(let ((count 0)
(end (length str))
(i 0)
x)
(while (< i end)
(setq x (aref str i))
(if (eq char x)
(setq count (1+ count)))
(setq i (1+ i)))
count))
While `my-count' is twice as fast, I'd still recommend to use
`cl-count', unless the code is very performance-critical.
Oleh
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-14 10:04 ` Oleh Krehel
@ 2015-10-14 17:06 ` Eli Zaretskii
0 siblings, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2015-10-14 17:06 UTC (permalink / raw)
To: help-gnu-emacs
> From: Oleh Krehel <ohwoeowho@gmail.com>
> Date: Wed, 14 Oct 2015 12:04:52 +0200
>
> (defun my-count (char str)
> (let ((count 0)
> (end (length str))
> (i 0)
> x)
> (while (< i end)
> (setq x (aref str i))
> (if (eq char x)
> (setq count (1+ count)))
> (setq i (1+ i)))
> count))
>
> While `my-count' is twice as fast, I'd still recommend to use
> `cl-count', unless the code is very performance-critical.
Why? There's nothing wrong with aref.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-13 17:43 ` Kaushal Modi
2015-10-13 19:07 ` Eli Zaretskii
2015-10-13 20:43 ` Michael Heerdegen
@ 2015-10-14 18:19 ` Noam Postavsky
2015-10-14 20:00 ` Kaushal Modi
2 siblings, 1 reply; 24+ messages in thread
From: Noam Postavsky @ 2015-10-14 18:19 UTC (permalink / raw)
To: help-gnu-emacs
Kaushal Modi <kaushal.modi <at> gmail.com> writes:
> I ran the below wrapper progn block couple of times and I got
> different results each time. Oddly enough, I even got negative
> execution times.
> What am I doing wrong?
`benchmark' is a function, you need to quote the code you pass to it,
otherwise you're measuring how long it takes to evaluate `2' (the result of
the progn block).
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to count the number of occurrences of a character in a string?
2015-10-14 18:19 ` Noam Postavsky
@ 2015-10-14 20:00 ` Kaushal Modi
0 siblings, 0 replies; 24+ messages in thread
From: Kaushal Modi @ 2015-10-14 20:00 UTC (permalink / raw)
To: Noam Postavsky; +Cc: Help Gnu Emacs mailing list
Thanks! That *was* the problem.
Code: https://gist.github.com/kaushalmodi/ab487f63727381179f61
--
Kaushal Modi
On Wed, Oct 14, 2015 at 2:19 PM, Noam Postavsky <
npostavs@users.sourceforge.net> wrote:
> Kaushal Modi <kaushal.modi <at> gmail.com> writes:
> > I ran the below wrapper progn block couple of times and I got
> > different results each time. Oddly enough, I even got negative
> > execution times.
> > What am I doing wrong?
>
> `benchmark' is a function, you need to quote the code you pass to it,
> otherwise you're measuring how long it takes to evaluate `2' (the result of
> the progn block).
>
>
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2015-10-14 20:00 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-12 19:45 How to count the number of occurrences of a character in a string? Marcin Borkowski
2015-10-12 21:43 ` Kaushal Modi
2015-10-12 23:27 ` Nick Dokos
2015-10-13 1:18 ` Stefan Monnier
2015-10-13 16:06 ` Kaushal Modi
2015-10-13 16:31 ` Kaushal Modi
2015-10-13 16:48 ` Eli Zaretskii
2015-10-13 17:41 ` Eli Zaretskii
2015-10-13 17:43 ` Kaushal Modi
2015-10-13 19:07 ` Eli Zaretskii
2015-10-13 19:56 ` Kaushal Modi
2015-10-13 20:17 ` Eli Zaretskii
2015-10-13 20:41 ` Kaushal Modi
[not found] ` <mailman.267.1444767491.7904.help-gnu-emacs@gnu.org>
2015-10-13 20:46 ` Brendan Halpin
2015-10-13 21:07 ` Kaushal Modi
[not found] ` <mailman.273.1444770543.7904.help-gnu-emacs@gnu.org>
2015-10-13 22:44 ` Joost Kremers
2015-10-14 10:04 ` Oleh Krehel
2015-10-14 17:06 ` Eli Zaretskii
2015-10-13 20:43 ` Michael Heerdegen
2015-10-13 20:59 ` Charles Curley
2015-10-14 18:19 ` Noam Postavsky
2015-10-14 20:00 ` Kaushal Modi
2015-10-13 22:00 ` Emanuel Berg
[not found] <mailman.164.1444679125.7904.help-gnu-emacs@gnu.org>
2015-10-12 23:35 ` Joost Kremers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).