branch: elpa/flamegraph
commit 38e593772a2a5e8e8dd204d29b239aacff53ef27
Author: Dmitry Gutov <[email protected]>
Commit: Dmitry Gutov <[email protected]>

    Performance improvements
---
 flamegraph.el | 37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/flamegraph.el b/flamegraph.el
index 287c35596a..65d6bd8d98 100644
--- a/flamegraph.el
+++ b/flamegraph.el
@@ -147,6 +147,17 @@ The same NAME always maps to the same color, as in classic 
flame graphs."
   "Format COUNT as a percentage of TOTAL with ~3 significant figures."
   (format "%.3g%%" (/ (* 100.0 count) total)))
 
+(defun flamegraph--help-echo (_window object pos)
+  (let ((frame (get-text-property pos 'flamegraph-frame object)))
+    (when (and frame (bufferp object))
+      (let* ((node (flamegraph-frame-node frame))
+             (count (profiler-calltree-count node))
+             (total (buffer-local-value 'flamegraph--grand-total object)))
+        (format "%s  —  %s (%s of total)"
+                (flamegraph--entry-name (profiler-calltree-entry node))
+                (profiler-format-number count)
+                (flamegraph--percent count total))))))
+
 ;;; Text renderer
 
 ;; Rows are laid out in pixels using `(space :align-to PIXEL)'.  Because
@@ -168,9 +179,9 @@ The same NAME always maps to the same color, as in classic 
flame graphs."
                (and win (window-body-width win t)))
              (* 80 cw)))))
 
-(defun flamegraph--render-text (frames max-depth grand-total)
+(defun flamegraph--render-text (frames max-depth)
   "Draw FRAMES into the current buffer, one row per depth.
-MAX-DEPTH is the deepest row; GRAND-TOTAL the whole-profile count."
+MAX-DEPTH is the deepest row."
   (let* ((cw (frame-char-width))
          (total-px (flamegraph--canvas-width))
          (border (if (display-graphic-p) flamegraph-frame-border 0))
@@ -194,7 +205,6 @@ MAX-DEPTH is the deepest row; GRAND-TOTAL the whole-profile 
count."
                      (boxl (if insetp (+ x0 border) x0))
                      (boxr (if insetp (- x1 border) x1))
                      (node (flamegraph-frame-node frame))
-                     (count (profiler-calltree-count node))
                      (name (flamegraph--entry-name
                             (profiler-calltree-entry node)))
                      ;; Truncate the name to what fits; no ellipsis.
@@ -205,10 +215,7 @@ MAX-DEPTH is the deepest row; GRAND-TOTAL the 
whole-profile count."
                                               :foreground "black")
                                   'mouse-face 'highlight
                                   'flamegraph-frame frame
-                                  'help-echo
-                                  (format "%s  —  %s (%s of total)"
-                                          name (profiler-format-number count)
-                                          (flamegraph--percent count 
grand-total)))))
+                                  'help-echo #'flamegraph--help-echo)))
           ;; Empty background gap, up to the box's left edge.
           (insert (propertize " " 'display `(space :align-to (,boxl))))
           (push (point) positions)
@@ -255,12 +262,12 @@ outermost frames.")
 (defun flamegraph--draw ()
   "(Re)draw the flame graph in the current buffer."
   (let ((inhibit-read-only t)
+        (inhibit-modification-hooks t)
         (root (or flamegraph--root flamegraph--top)))
     (erase-buffer)
     (pcase-let ((`(,frames ,_total ,max-depth)
                  (flamegraph--frames root)))
-      (flamegraph--render-text
-       frames max-depth flamegraph--grand-total))
+      (flamegraph--render-text frames max-depth))
     ;; Double % so percentages aren't taken as mode-line %-constructs.
     (setq header-line-format
           (string-replace "%" "%%" (flamegraph--header)))
@@ -425,11 +432,6 @@ Uses the CPU profile if one was recorded, otherwise the 
memory profile."
 
 ;;; Folded stacks
 
-(defun flamegraph--find-child (node name)
-  "Return NODE's child whose entry is the string NAME, or nil."
-  (cl-find name (profiler-calltree-children node)
-           :key #'profiler-calltree-entry :test #'equal))
-
 (defun flamegraph--read-folded (filename)
   "Parse folded stacks in FILENAME into a calltree root node.
 Each non-empty line has the form \"FRAME;FRAME;... COUNT\", outermost
@@ -446,7 +448,12 @@ COUNT is added to every frame along the stack."
             (let ((node root)
                   (count (string-to-number (match-string 2 line))))
               (dolist (frame (split-string (match-string 1 line) ";" t))
-                (let ((child (flamegraph--find-child node frame)))
+                (let ((children (profiler-calltree-children node))
+                      (child nil))
+                  (while children
+                    (if (equal (profiler-calltree-entry (car children)) frame)
+                        (setq child (car children) children nil)
+                      (setq children (cdr children))))
                   (unless child
                     (setq child (profiler-make-calltree :entry frame :parent 
node))
                     (push child (profiler-calltree-children node)))

Reply via email to