unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* What does all-completions with COLLECTION == obarray return?
@ 2015-04-04 16:43 Michael Heerdegen
  2015-04-05  4:12 ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2015-04-04 16:43 UTC (permalink / raw)
  To: Emacs Development

Hello,

in emacs -Q,

(cons
 (length obarray)
 (length (all-completions "" obarray)))

    ==> (1511 . 15039)

I don't understand why the second value is so much larger than the
first.  I would expect as many completions as interned symbols.


Some background:

In helm, we've found a really weird bug.  If you repeatedly evaluate,
with helm-mode on, the following:

--8<---------------cut here---------------start------------->8---
(let* ((hi-lock-face-defaults
        (list
         "hi-yellow"
         "hi-pink"
         "hi-green"
         "hi-blue"
         "hi-black-b"
         "hi-blue-b"
         "hi-red-b"
         "hi-green-b"
         "hi-black-hb")))
  (completing-read
   (format "Highlight using face (default %s): "
           (car hi-lock-face-defaults))
   (all-completions "" obarray)
   'facep t nil 'face-name-history hi-lock-face-defaults))
--8<---------------cut here---------------end--------------->8---

(just say C-g at each prompt), after ten or so iterations, it gets slow,
every time it takes twice as long as before until the prompt appears.
Soon it gets completely unusable freezing Emacs for a minute.

I debugged this and found out that after performing this test,
(all-completions "" obarray) does return a list with ~ a million
elements.  Since we use all-completions to create a candidate list for
completion, we have a million candidates then, and this is what makes
Helm slow.

(length (all-completions "" obarray)) seems to grow exponentially for
every iteration of the above code, but obarray remains constant in size.

What could be happening here?


Thanks,

Michael.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: What does all-completions with COLLECTION == obarray return?
  2015-04-04 16:43 What does all-completions with COLLECTION == obarray return? Michael Heerdegen
@ 2015-04-05  4:12 ` Stefan Monnier
  2015-04-05 18:48   ` Michael Heerdegen
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2015-04-05  4:12 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Emacs Development

>  (length obarray)

Doesn't do what you think.  An obarray is a vector, and this just
returns the number of buckets in the hash-table.

Check "grep 1511 src/*.[ch]".


        Stefan



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: What does all-completions with COLLECTION == obarray return?
  2015-04-05  4:12 ` Stefan Monnier
@ 2015-04-05 18:48   ` Michael Heerdegen
  2015-04-06  4:01     ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2015-04-05 18:48 UTC (permalink / raw)
  To: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> >  (length obarray)
>
> Doesn't do what you think.  An obarray is a vector, and this just
> returns the number of buckets in the hash-table.

Thanks, my imagination of obarray was indeed wrong.

I continued debugging, and found out that when following the recipe in
helm I posted, the obarray seems to be filled with more and more symbols
- with only a few names.

I wrote this test function:

--8<---------------cut here---------------start------------->8---
(defun my-find-doubles ()
  (let ((table (make-hash-table :size 65000 :test #'equal)))
    (mapatoms (lambda (symbol) (if (gethash (symbol-name symbol) table)
                              (message "%S" (symbol-name symbol))
                            (puthash (symbol-name symbol) t table))))))
--8<---------------cut here---------------end--------------->8---

I would expect that whenever it gets called, it produces no output.

Before running the recipe, it indeed prints nothing.  But after the
first time:

"Bahá'í Date"
"Insert Bahá'í"
"…"

These three symbol names all include non-ascii chars, sorry if they
should have been posted incorrectly.

The effect seems to be exponential or worse, soon I see:


"Bahá'í Date" [8191 times]
"Insert Bahá'í" [8191 times]
"…" [8191 times]

after a few more trials.

What could be happening here?


Thanks,

Michael.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: What does all-completions with COLLECTION == obarray return?
  2015-04-05 18:48   ` Michael Heerdegen
@ 2015-04-06  4:01     ` Stefan Monnier
  2015-04-08  9:42       ` Michael Heerdegen
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2015-04-06  4:01 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

> I continued debugging, and found out that when following the recipe in
> helm I posted, the obarray seems to be filled with more and more symbols
> - with only a few names.

The recipe seems to do something nasty to the obarray.  But I don't
recall seeing this recipe.  Could you resend it?


        Stefan



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: What does all-completions with COLLECTION == obarray return?
  2015-04-06  4:01     ` Stefan Monnier
@ 2015-04-08  9:42       ` Michael Heerdegen
  2015-04-08 13:46         ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2015-04-08  9:42 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan Monnier <monnier@IRO.UMontreal.CA> writes:

> The recipe seems to do something nasty to the obarray.  But I don't
> recall seeing this recipe.  Could you resend it?

It was just this:

--8<---------------cut here---------------start------------->8---
(let* ((hi-lock-face-defaults
        (list
         "hi-yellow"
         "hi-pink"
         "hi-green"
         "hi-blue"
         "hi-black-b"
         "hi-blue-b"
         "hi-red-b"
         "hi-green-b"
         "hi-black-hb")))
  (completing-read
   (format "Highlight using face (default %s): "
           (car hi-lock-face-defaults))
   (all-completions "" obarray)
   'facep t nil 'face-name-history hi-lock-face-defaults))
--8<---------------cut here---------------end--------------->8---

with helm-mode on.

AFAICT we don't try to manipulate obarray directly (of course).  What
nasty things could we be doing?


Thanks,

Michael.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: What does all-completions with COLLECTION == obarray return?
  2015-04-08  9:42       ` Michael Heerdegen
@ 2015-04-08 13:46         ` Stefan Monnier
  2015-04-08 16:38           ` Michael Heerdegen
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2015-04-08 13:46 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

>> The recipe seems to do something nasty to the obarray.  But I don't
>> recall seeing this recipe.  Could you resend it?

> It was just this:

> --8<---------------cut here---------------start------------->8---
> (let* ((hi-lock-face-defaults
>         (list
>          "hi-yellow"
>          "hi-pink"
>          "hi-green"
>          "hi-blue"
>          "hi-black-b"
>          "hi-blue-b"
>          "hi-red-b"
>          "hi-green-b"
>          "hi-black-hb")))
>   (completing-read
>    (format "Highlight using face (default %s): "
>            (car hi-lock-face-defaults))
>    (all-completions "" obarray)
>    'facep t nil 'face-name-history hi-lock-face-defaults))
> --8<---------------cut here---------------end--------------->8---

This code looks OK (though I'd pass obarray directly without going
through all-completions).

> with helm-mode on.
> AFAICT we don't try to manipulate obarray directly (of course).  What
> nasty things could we be doing?

I don't know.  I expected the recipe to demonstrate the kinds of
problems you're seeing, so I guess I lack other parts of the recipe.


        Stefan



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: What does all-completions with COLLECTION == obarray return?
  2015-04-08 13:46         ` Stefan Monnier
@ 2015-04-08 16:38           ` Michael Heerdegen
  2015-04-15 13:56             ` Michael Heerdegen
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2015-04-08 16:38 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> I don't know.  I expected the recipe to demonstrate the kinds of
> problems you're seeing, so I guess I lack other parts of the recipe.

The "other parts" were just that if you repeat the recipe eight times or
so, Emacs gets slower an then freezes for longer and longer periods
before the minibuffer appears, and that is because obarray grows so
massively.  All that in a minimal helm environment - helm.sh, if it says
something to you.

The answer must be in the implementation of helminized completing read,
but I could not find something obviously unorthodox in the code wrt
obarray.

I'll try to step through the code and find out where something gets
actually added to obarray.


Thanks,

Michael.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: What does all-completions with COLLECTION == obarray return?
  2015-04-08 16:38           ` Michael Heerdegen
@ 2015-04-15 13:56             ` Michael Heerdegen
  0 siblings, 0 replies; 8+ messages in thread
From: Michael Heerdegen @ 2015-04-15 13:56 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Thierry Volpiatto, emacs-devel

Michael Heerdegen <michael_heerdegen@web.de> writes:

> I'll try to step through the code and find out where something gets
> actually added to obarray.

I was lucky and could condense a recipe for emacs -Q out of the Helm
code we use:

--8<---------------cut here---------------start------------->8---
(progn
  (intern "Bahá'í Date") ;this happens when requiring org
  (let* ((collection (all-completions "" obarray))
         (test #'facep)
         (predicate `(lambda (elm)
                       (condition-case err
                           (if (eq (quote ,test) 'commandp)
                               (funcall (quote ,test) (intern elm))
                             (funcall (quote ,test) elm))
                         (wrong-type-argument
                          (funcall (quote ,test) (intern elm)))))))
    (ignore (all-completions "" collection predicate))
    ;; Test if "Bahá'í Date" is the name of more than one interned symbol
    (when (let ((i 0))
            (catch 'done
              (mapatoms (lambda (s) (when (string= (symbol-name s) "Bahá'í Date")
                                 (if (< i 1) (setq i 1) (throw 'done t)))))
              nil))
      (message "Gotcha!"))))
--8<---------------cut here---------------end--------------->8---

Copy this into scratch in emacs -Q and hit C-x C-e.  I get "Gotcha!",
meaning that after evaluation, there is more than one interned symbol
named "Bahá'í Date".

I guess this should not happen, so it is a bug in Emacs in think.


Thanks,

Michael.
 



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-04-15 13:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-04 16:43 What does all-completions with COLLECTION == obarray return? Michael Heerdegen
2015-04-05  4:12 ` Stefan Monnier
2015-04-05 18:48   ` Michael Heerdegen
2015-04-06  4:01     ` Stefan Monnier
2015-04-08  9:42       ` Michael Heerdegen
2015-04-08 13:46         ` Stefan Monnier
2015-04-08 16:38           ` Michael Heerdegen
2015-04-15 13:56             ` Michael Heerdegen

Code repositories for project(s) associated with this public inbox

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

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).