unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Slow frame creation when many faces defined
@ 2005-11-12 19:56 David Reitter
  2005-11-12 21:07 ` Drew Adams
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: David Reitter @ 2005-11-12 19:56 UTC (permalink / raw)


I've got a question about a noticeable lag in frame creation when  
many frames are defined. This can be reproduced with

(let ((n 0))
(while (< n 1000)
        (make-face (make-symbol "someface"))
        (setq n (1+ n)))
)

then do C-x 5 2. This creates a lag of several seconds.;

In a realistic setting I've got around 400-600 faces listed in face- 
new-frame-defaults, but they are obviously more complex than what is  
created in the simplified example above.

The reason for that is that in a longer session, more and more faces  
are defined as I apply different sets of themes depending on the  
different types of buffers I use. Some of them -- those that I use as  
defaults for different modes -- are saved in my custom-file.  (I'm  
using color-theme to define the faces.)

What is the recommended strategy for managing faces?
Can I make a buffer-local face that is not also created globally and  
avoid the persistency of faces?
Can I delete a face?
Would themes provide a solution here?

Can frame creation in the presence of face definitions be sped up?
I noticed that the (face-set-after-frame-default frame) call in x- 
create-frame-with-faces causes. There is a "(dolist (face (face- 
list)) ... )" in that function, which slows things down a lot.

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

* RE: Slow frame creation when many faces defined
  2005-11-12 19:56 Slow frame creation when many faces defined David Reitter
@ 2005-11-12 21:07 ` Drew Adams
  2005-11-13 20:54 ` Richard M. Stallman
  2005-11-15  8:11 ` YAMAMOTO Mitsuharu
  2 siblings, 0 replies; 9+ messages in thread
From: Drew Adams @ 2005-11-12 21:07 UTC (permalink / raw)


    I've got a question about a noticeable lag in frame creation when
    many frames are defined. This can be reproduced with

    (let ((n 0))
    (while (< n 1000)
       (make-face (make-symbol "someface"))
       (setq n (1+ n))))

    then do C-x 5 2. This creates a lag of several seconds.

This is neither here nor there, but:

The frame creation appears _instantaneous_ with Emacs 20 on my (average)
machine with Windows XP. Using 10000 instead of 1000, it takes about 3
seconds to evaluate the above expression and about 3 seconds to open the new
frame.

I confirm that, even with "only" 1000, it takes a couple of seconds to open
the frame with Emacs 22 (July snapshot of CVS).

So, there is maybe an order of magnitude difference between Emacs 20 and
Emacs 22 in this regard. I don't know if that's significant in any way, but
there it is.

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

* Re: Slow frame creation when many faces defined
  2005-11-12 19:56 Slow frame creation when many faces defined David Reitter
  2005-11-12 21:07 ` Drew Adams
@ 2005-11-13 20:54 ` Richard M. Stallman
  2005-11-13 23:38   ` Kim F. Storm
  2005-11-15  8:11 ` YAMAMOTO Mitsuharu
  2 siblings, 1 reply; 9+ messages in thread
From: Richard M. Stallman @ 2005-11-13 20:54 UTC (permalink / raw)
  Cc: emacs-devel

    In a realistic setting I've got around 400-600 faces listed in face- 
    new-frame-defaults, but they are obviously more complex than what is  
    created in the simplified example above.

It might be possible to optimize the code that handles faces
when creating a frame.  That code is very complex, has many levels
that were written at different times, and very likely is doing a lot
of things the hard way.  Rewriting it from scratch, after making a new
design that is clear, could probably make it much faster.

That would be a useful thing to do, but now is not the time to install
it.  I will add it to etc/TODO.

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

* Re: Slow frame creation when many faces defined
  2005-11-13 20:54 ` Richard M. Stallman
@ 2005-11-13 23:38   ` Kim F. Storm
  2005-11-14  8:33     ` David Reitter
  0 siblings, 1 reply; 9+ messages in thread
From: Kim F. Storm @ 2005-11-13 23:38 UTC (permalink / raw)
  Cc: David Reitter, emacs-devel

"Richard M. Stallman" <rms@gnu.org> writes:

>     In a realistic setting I've got around 400-600 faces listed in face- 
>     new-frame-defaults, but they are obviously more complex than what is  
>     created in the simplified example above.
>
> It might be possible to optimize the code that handles faces
> when creating a frame.  That code is very complex, has many levels
> that were written at different times, and very likely is doing a lot
> of things the hard way.  Rewriting it from scratch, after making a new
> design that is clear, could probably make it much faster.
>
> That would be a useful thing to do, but now is not the time to install
> it.  I will add it to etc/TODO.

It would be interesting if someone would do some profiling of the
relevant code to see if there is a specific loop that accounts for
most of the time spent here.  It could be something which was easy
to optimize once we know what it is.

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

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

* Re: Slow frame creation when many faces defined
  2005-11-13 23:38   ` Kim F. Storm
@ 2005-11-14  8:33     ` David Reitter
  2005-11-14  9:24       ` Kim F. Storm
  0 siblings, 1 reply; 9+ messages in thread
From: David Reitter @ 2005-11-14  8:33 UTC (permalink / raw)
  Cc: rms, emacs-devel

On 13 Nov 2005, at 23:38, Kim F. Storm wrote:

> It would be interesting if someone would do some profiling of the
> relevant code to see if there is a specific loop that accounts for
> most of the time spent here.  It could be something which was easy
> to optimize once we know what it is.

This is the loop you're looking for. It's in face-set-after-frame- 
default (faces.el):

(dolist (face (face-list))
     ;; Don't let frame creation fail because of an invalid face spec.
     (condition-case ()
	(when (not (equal face 'default))
	  (face-spec-set face (face-user-default-spec face) frame)
	  (internal-merge-in-global-face face frame)
	   (when (and (memq window-system '(x w32 mac))
		     (or (not (boundp 'inhibit-default-face-x-resources))
			 (not (eq face 'default))))
	    (make-face-x-resource-internal face frame))
	  )
       (error nil)))


Note: (not (eq face 'default)) is always t inside the (or ...),

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

* Re: Slow frame creation when many faces defined
  2005-11-14  8:33     ` David Reitter
@ 2005-11-14  9:24       ` Kim F. Storm
  0 siblings, 0 replies; 9+ messages in thread
From: Kim F. Storm @ 2005-11-14  9:24 UTC (permalink / raw)
  Cc: rms, emacs-devel

David Reitter <david.reitter@gmail.com> writes:

> On 13 Nov 2005, at 23:38, Kim F. Storm wrote:
>
>> It would be interesting if someone would do some profiling of the
>> relevant code to see if there is a specific loop that accounts for
>> most of the time spent here.  It could be something which was easy
>> to optimize once we know what it is.
>
> This is the loop you're looking for. It's in face-set-after-frame- 
> default (faces.el):
>
> (dolist (face (face-list))
>      ;; Don't let frame creation fail because of an invalid face spec.
>      (condition-case ()
> 	(when (not (equal face 'default))
> 	  (face-spec-set face (face-user-default-spec face) frame)
> 	  (internal-merge-in-global-face face frame)
> 	   (when (and (memq window-system '(x w32 mac))
> 		     (or (not (boundp 'inhibit-default-face-x-resources))
> 			 (not (eq face 'default))))
> 	    (make-face-x-resource-internal face frame))
> 	  )
>        (error nil)))
>
>
> Note: (not (eq face 'default)) is always t inside the (or ...),

I think this can be simplified to:

   ;; Don't let frame creation fail because of an invalid face spec.
   (condition-case ()
      (dolist (face (face-list))
	(when (not (equal face 'default))
	  (face-spec-set face (face-user-default-spec face) frame)
	  (internal-merge-in-global-face face frame)
	   (when (memq window-system '(x w32 mac))
	      (make-face-x-resource-internal face frame))))
    (error nil))


Does that make it any faster?

If not (and I doubt it has any great effect), I would like someone to
study the internals of the functions called here to see if they do
something sub-optimal.

What did the previous version (which ran this faster) do here?
What specific part was added that could explain the slow-down?

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

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

* Re: Slow frame creation when many faces defined
  2005-11-12 19:56 Slow frame creation when many faces defined David Reitter
  2005-11-12 21:07 ` Drew Adams
  2005-11-13 20:54 ` Richard M. Stallman
@ 2005-11-15  8:11 ` YAMAMOTO Mitsuharu
  2005-11-15 11:51   ` David Reitter
  2 siblings, 1 reply; 9+ messages in thread
From: YAMAMOTO Mitsuharu @ 2005-11-15  8:11 UTC (permalink / raw)
  Cc: Emacs-Devel '

>>>>> On Sat, 12 Nov 2005 19:56:24 +0000, David Reitter <david.reitter@gmail.com> said:

> I've got a question about a noticeable lag in frame creation when
> many frames are defined. This can be reproduced with

> (let ((n 0)) (while (< n 1000) (make-face (make-symbol "someface"))
> (setq n (1+ n))) )

> then do C-x 5 2. This creates a lag of several seconds.;

As you may have already noticed, the Carbon version is much slower
than the X11 version for this example.  The reason is that the X
Resource Manager emulation function consumes some short-lived objects
for each query, and a number of calls of this function causes frequent
GCs.

I installed some changes for this problem.  Frame creation is still
slow, but should be better than before.

				     YAMAMOTO Mitsuharu
				mituharu@math.s.chiba-u.ac.jp

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

* Re: Slow frame creation when many faces defined
  2005-11-15  8:11 ` YAMAMOTO Mitsuharu
@ 2005-11-15 11:51   ` David Reitter
  2005-11-15 16:47     ` Drew Adams
  0 siblings, 1 reply; 9+ messages in thread
From: David Reitter @ 2005-11-15 11:51 UTC (permalink / raw)
  Cc: Emacs-Devel '

On 15 Nov 2005, at 08:11, YAMAMOTO Mitsuharu wrote:
>
> As you may have already noticed, the Carbon version is much slower
> than the X11 version for this example.  The reason is that the X
> Resource Manager emulation function consumes some short-lived objects
> for each query, and a number of calls of this function causes frequent
> GCs.
>
> I installed some changes for this problem.  Frame creation is still
> slow, but should be better than before.

Thanks. It's looking significantly better now indeed.

The underlying problem in terms of faces management remains: a lot of  
copying and checking (of the global list) when a new frame is  
created, and a global list of faces that gets longer and longer over  
time. It still takes too much time, in particular since people are  
used to a zippy Emacs...

- D

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

* RE: Slow frame creation when many faces defined
  2005-11-15 11:51   ` David Reitter
@ 2005-11-15 16:47     ` Drew Adams
  0 siblings, 0 replies; 9+ messages in thread
From: Drew Adams @ 2005-11-15 16:47 UTC (permalink / raw)


    It still takes too much time, in particular since people are  
    used to a zippy Emacs...

Not to worry. Emacs will always be Zippy.  Yow!

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

end of thread, other threads:[~2005-11-15 16:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-12 19:56 Slow frame creation when many faces defined David Reitter
2005-11-12 21:07 ` Drew Adams
2005-11-13 20:54 ` Richard M. Stallman
2005-11-13 23:38   ` Kim F. Storm
2005-11-14  8:33     ` David Reitter
2005-11-14  9:24       ` Kim F. Storm
2005-11-15  8:11 ` YAMAMOTO Mitsuharu
2005-11-15 11:51   ` David Reitter
2005-11-15 16:47     ` Drew Adams

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