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

    Drop cold callees from describe-buffer snippets
    
    Add flamegraph-call-site-threshold (default 2%): callees whose share of
    the described frame's count falls below it are no longer highlighted in
    the source snippet, nor are their lines pulled into it.
---
 README.md                |  1 +
 flamegraph.el            | 15 +++++++++++++--
 test/flamegraph-tests.el | 19 +++++++++++++++++++
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 9d48b1d61c..1853c9d0c3 100644
--- a/README.md
+++ b/README.md
@@ -153,6 +153,7 @@ canonical [CPU Flame Graphs][cpufg] article.
 | `flamegraph-frame-border` | Pixel gap between adjacent frame boxes |
 | `flamegraph-text-padding` | Pixels between a frame's left edge and its label 
|
 | `flamegraph-source-directory` | Where to resolve relative paths when 
visiting source |
+| `flamegraph-call-site-threshold` | Min sample share for a callee to appear 
in the describe-buffer snippet (default: 2%) |
 
 | Face | Purpose |
 | --- | --- |
diff --git a/flamegraph.el b/flamegraph.el
index c42410e213..95d3186add 100644
--- a/flamegraph.el
+++ b/flamegraph.el
@@ -84,6 +84,12 @@ FILE:LINE location.  If nil, paths are resolved against the 
directory of
 the data file the graph was loaded from."
   :type '(choice (const :tag "Data file's directory" nil) directory))
 
+(defcustom flamegraph-call-site-threshold 0.02
+  "Minimum share of a frame's samples for a callee to appear in its snippet.
+Callees below this fraction (of the described frame's count) are not
+highlighted in the describe-buffer source."
+  :type 'float)
+
 (defface flamegraph-call-site-hot
   '((((background light)) :background "#ff9b3d")
     (((background dark))  :background "#9c4a1c"))
@@ -683,8 +689,10 @@ in completely unrelated forms (a literal `(if …)' 
elsewhere), or
 may not exist at all (`dolist' → `while'/`let').  Only real function
 matches narrow, which is what preserves structural attribution.
 
-Each region is (POS-BEG POS-END WEIGHT), WEIGHT being the callee's
-share of NODE's count, for heat styling."
+Callees below `flamegraph-call-site-threshold' of NODE's count are
+dropped along with their subtree.  Each region is (POS-BEG POS-END
+WEIGHT), WEIGHT being the callee's share of NODE's count, for heat
+styling."
   (let ((total (max 1 (profiler-calltree-count node)))
         regions)
     (cl-labels
@@ -698,6 +706,9 @@ share of NODE's count, for heat styling."
                 (skip
                  ;; Special form — transparent descend, no narrowing.
                  (walk k region))
+                ((< weight flamegraph-call-site-threshold)
+                 ;; Too cold to be worth showing — drop it and its subtree.
+                 nil)
                 ((flamegraph--callee-name-acceptable-p name)
                  ;; Real function — search in the current region.
                  ;; Each match is highlighted and narrows the search
diff --git a/test/flamegraph-tests.el b/test/flamegraph-tests.el
index 8efadf6f7f..ae3800d6f8 100644
--- a/test/flamegraph-tests.el
+++ b/test/flamegraph-tests.el
@@ -193,6 +193,25 @@ callees outside it must still be found."
                      outer (point-min) (point-max))))
       (should (equal (flamegraph-test--region-texts regions) '("foo"))))))
 
+(ert-deftest flamegraph-test-walker-below-threshold-dropped ()
+  "Callees below `flamegraph-call-site-threshold' are dropped with subtree.
+hot at 50% is kept; cold at 1% (and its child) are not."
+  (flamegraph-test--with-elisp-source
+      "(defun outer ()
+  (hot (deep))
+  (cold))"
+    (let* ((deep  (profiler-make-calltree :entry 'deep :count 1))
+           (hot   (profiler-make-calltree :entry 'hot :count 50
+                                          :children (list deep)))
+           (cold  (profiler-make-calltree :entry 'cold :count 1))
+           (outer (profiler-make-calltree :entry 'outer :count 100
+                                          :children (list hot cold)))
+           (flamegraph-call-site-threshold 0.02)
+           (regions (flamegraph--collect-nested-call-sites
+                     outer (point-min) (point-max))))
+      ;; hot (50%) kept; deep is 1% of outer -> dropped; cold (1%) dropped.
+      (should (equal (flamegraph-test--region-texts regions) '("hot"))))))
+
 ;;; `flamegraph--symbol-location'
 
 (ert-deftest flamegraph-test-symbol-location ()

Reply via email to