all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* 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 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 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 --
     [not found] <mailman.164.1444679125.7904.help-gnu-emacs@gnu.org>
2015-10-12 23:35 ` How to count the number of occurrences of a character in a string? Joost Kremers
2015-10-12 19:45 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

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.