Better performance
Everything can always be faster, but I have been able to cause perceptible delays within real world documents so a speed-up would be useful.
I'm not sure what approaches would work.
Hooking onto modification hooks to cache seems like a recipe for difficult debugging but it's doable.
I've noticed that motion between headings with lots of hidden child nodes can be slow in org, so perhaps the cost of invalidating caches could be pushed into org :).
Forgive the intrusion, but I am interested in this. I suspect that using a heavily functional approach is going to be inherently slow because it tends to at least double or triple the number of regex searches done. For example, if you're looking for a word in an Org file, using org-map-entries to search every node, one-by-one, is going to be much slower than simply searching for that word directly, because of all the regex searches that must be run to find the boundaries of each node.
A while back I tried a functional approach with helm-org-rifle, and when I profiled it, it was definitely slower, even though the code was more elegant, so I set aside that project...indefinitely. :)
In case you find it helpful, here's a macro I used for profiling. If you run it from an Org source block, it will put the results in a results block, making them easy to handle:
(defmacro profile-rifle (times &rest body)
`(let (output)
(dolist (p '("helm-" "org-" "string-" "s-" "buffer-" "append" "delq" "map" "list" "car" "save-" "outline-" "delete-dups" "sort" "line-" "nth" "concat" "char-to-string" "rx-" "goto-" "when" "search-" "re-"))
(elp-instrument-package p))
(dotimes (x ,times)
,@body)
(elp-results)
(elp-restore-all)
(point-min)
(forward-line 20)
(delete-region (point) (point-max))
(setq output (buffer-substring-no-properties (point-min) (point-max)))
(kill-buffer)
(delete-window)
output))
You can use it like this:
(profile-rifle 10 (function-to-profile))
The profiling code looks interesting.
org-map-entries to search every node, one-by-one, is going to be much slower
Interesting... I would have assumed the overhead wasn't that large.
So the big speed up I got (although I wasn't really doing formal timing since helm is hard to script), was by reimplementing a version of org-map-region that only went to a certain depth. This again isn't really relevant for helm-org-rifle.
The problem in orgnav are slightly different from org-helm-rifle insofar as for me only searching the tree up to a certain depth is the normal use case. This gives you speeds ups by ignoring lower levels, and makes things like slow motion between org headings that contain a lot of text relevant.
Anyway yes... I should probably do some profiling before I start forming opinions because they are almost certainly wrong.