emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] (Updated) Run hook when variable is set


From: Kelly Dean
Subject: Re: [PATCH] (Updated) Run hook when variable is set
Date: Fri, 06 Feb 2015 09:55:42 +0000

As a followup to my previous message, here are some benchmarks to test the 
worst-case performance impact of the varhook-single patch. This is without any 
changes to the patch; the «hooked» bit is still separate from «constant», so 
try_run_varhook is executed every time a non-lexical variable is set.

This is on an Intel Core 2 (more than 8 years old, so not taking advantage of 
any recent CPU optimizations, but it does have a branch predictor, which is an 
ancient feature). Emacs is compiled with its default optimization settings, 
with and without the patch.

Note, to compile 24.4 with the patch, you have to add to the top of data.c the 
line:
static Lisp_Object Qvarhook, Qglobal, Qbuf_local, Qdyn_local, Qdyn_bind, 
Qdyn_unbind, Qinvalid;

Do emacs -Q, then:
(require 'cl)
(setq x 0)
(defun test ()
  (benchmark-run-compiled 100000 (incf x)))

With Emacs 24.4, without the patch:
(test) → (0.009720718000000003 0 0.0)
(test) → (0.007469938999999995 0 0.0)
(test) → (0.007450257000000002 0 0.0)

With the patch:
(test) → (0.006218317000000001 0 0.0)
(test) → (0.0055950570000000005 0 0.0)
(test) → (0.005777339000000006 0 0.0)

IOW, varhook miraculously makes Emacs faster! ;-)

Ok, another couple test runs:

Without the patch:
(test) → (0.006397249999999993 0 0.0)
(test) → (0.006253384000000001 0 0.0)
(test) → (0.006264767000000004 0 0.0)

With the patch:
(test) → (0.007369438000000006 0 0.0)
(test) → (0.006640647999999999 0 0.0)
(test) → (0.007056691999999989 0 0.0)

With multiple runs, the difference is below the accuracy of measurement.

Continuing onward with the patch:
(hook 'x) ; But «varhook» is still nil (i.e. there's no handler function)
;; Now, run_varhook will be called each time x is incremented.
(test) → (0.04964255199999999 0 0.0)
(test) → (0.046831024 0 0.0)
(test) → (0.047073512 0 0.0)
(add-hook 'varhook (lambda (_sym _env _val) nil))
(test) → (0.07824081199999999 0 0.0)
(test) → (0.07892686900000001 0 0.0)
(test) → (0.07999398 0 0.0)
(unhook 'x)
(test) → (0.00680763899999999 0 0.0)
(test) → (0.005905495999999996 0 0.0)
(test) → (0.006095260000000005 0 0.0)

All as expected. After unhooking, the results are again indistinguishable from 
the results of Emacs without the patch.

Another test:
(require 'cl)
(defun test1 ()
  (setq x 0)
  (benchmark-run-compiled
      (do () ((> x 100000)) (incf x))))

Without the patch:
(test1) → (0.010726432 0 0.0)
(test1) → (0.010739914 0 0.0)
(test1) → (0.010754511 0 0.0)

With the patch:
(test1) → (0.011321344 0 0.0)
(test1) → (0.011568507 0 0.0)
(test1) → (0.011352074 0 0.0)

Without the patch:
(test1) → (0.011268476 0 0.0)
(test1) → (0.011142896 0 0.0)
(test1) → (0.011574237 0 0.0)

With the patch:
(test1) → (0.011327352 0 0.0)
(test1) → (0.011323509 0 0.0)
(test1) → (0.011337811 0 0.0)

The difference is again below the accuracy of measurement.

Based on these results, I recommend against putting the «hooked» bit into the 
«constant» field. It wouldn't accomplish anything, and it would reduce the 
clarity of the source code.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]