[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: w3m tab line constantly consumes CPU
- From: Michael Heerdegen <michael_heerdegen@xxxxxx>
- Date: Mon, 21 Oct 2013 06:20:37 +0200
- X-ml-name: emacs-w3m
- X-mail-count: 12201
- References: <87k3haj8zk.fsf@xxxxxx> <b4m1u3f8ji4.fsf@xxxxxxx>
(B> In [emacs-w3m : No.12198] Michael Heerdegen wrote:
(B> > From time to time, I see Emacs constantly consuming CPU, ca. 10%. Emacs
(B> > doesn't hang, but consumes enough CPU to let my ventilator run all the
(B> > time.
(B> > It took some time to identify that w3m was the culprit, its tab line,
(B> > to be more precise. When the tab line is visible, `w3m-tab-line' and
(B> > `w3m-force-window-update' are constantly run, ca. 10 times per second.
(B> > Use `trace-function' to verify.
(B> Yes, I knew the tab line eats CPU not a little. I also tried `elp':
(B> M-x elp-instrument-package RET w3m RET
(B> Run emacs-w3m for a while...
(B> M-x elp-results RET
(B> (If necessary, do `M-x elp-reset-all RET' to reset the result.)
(B> According to the result, `w3m-tab-line' and `w3m-force-window-update'
(B> seem to waste time not so much. So, I was thinking we have nothing
(B> to have to do if those appetites don't grow anymore.
(BWhat you did doesn't necessarily reveal the misery, I think. The loop
(Bcauses a _redisplay_ every 0.1 seconds, and this is what eats CPU.
(BPresumably this isn't shown in your results, because `w3m-tab-line' is
(Bfast, and `w3m-force-window-update' terminates immediately before the
(Bredisplay was performed.
(BHow much CPU it costs depends on the contents of the current w3m window,
(Band what it displays. A complex page is more critical as "about:".
(BI checked with profiler.el, M-x profiler-start, etc. When I did nothing
(Bwith Emacs, 90% of the CPU time used by Emacs was consumed by the loop.
(BAbsolutely, it makes ca. 5% of CPU usage at my (quite new) laptop.
(B> > 3. So, after 0.1 seconds, `w3m-force-window-update' is called. This
(B> > redraws the window's header line, too, so we are back to 1. Ouch!
(B> > I don't want to make a suggestion on how to fix this because I don't
(B> > know the code well. We have to avoid the loop somehow.
(B> As you might think, another way to update the header line would
(B> be to make it event-driven. That is, to modify all the functions,
(B> that change the header line appearance, so as to call `w3m-tab-line'
(B> if and only if it is necessary.
(BWhen I analyze the current code, it makes no sense.
(BGrep for `w3m-tab-line'. It is only called at one single place in all
(Bw3m files: in the :eval of the header line format of w3m buffers. This
(Bis only called when a redisplay is performed - so why do we need to
(Btrigger another redisplay some time later?
(BAll functions that do stuff making a refresh of the header line
(Bnecessary should trigger a redisplay - and that's what they already do,
(BI think (else, we would never enter any loop).
(BSo, my guess is that removing
(B (run-at-time 0.1 nil
(B (lambda (buffer)
(B (when (buffer-live-p buffer)
(B (with-current-buffer buffer
(B (inline (w3m-force-window-update))
(B (setq w3m-tab-timer nil))))
(Bfrom `w3m-tab-line' would do nothing harmful but prevent successive
(Bunnecessary redisplays. A short test seems to confirm that.
(BIf we really face a situation where the tab line doesn't get updated, we
(Bwill just have to add an explicit redisplay. The current code is only
(Bhelpful in a situation where a w3m function does something that changes
(Bthe tabs, performs redisplay, and then does another thing changing
(Bthe tabs a second time. If there is really such a case, then we should
(BIMHO handle this case.
(BOr, do you mean we should even get rid of the :eval in the header-line
(Bformat? This would increase performance even more, but this is a
(BDo you really think that would be hard? I would think that we would
(Bjust need to recalculate the header line every time we explicitly
(Bperform redisplay from the code.