Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example of potential performance benefit of early exit in reduce
/* don't use this, it's just for a timing demonstration */
public class ReturningException extends RuntimeException {
transient public final Object data;
transient public final Object context;
public ReturningException(Object o){
this(null, o);
}
public ReturningException(Object c, Object o){
super("Not really an exception");
data = o;
context = c;
}
}
;this is not a recommended implementation, just a possible way to measure what early-exit can do
;this example lets you time internal-reduce with early exit without changing core code
(defmacro shortcut [sentinel & forms]
(let [context (gensym)]
`(try
~@(postwalk
(fn[term]
(if (and (list? term)
(= sentinel (first term)))
`(throw (ReturningException.
'~context ~@(rest term)))
term))
forms)
(catch ReturningException e#
(if
(= '~context (.context e#))
(.data e#)
(throw e#))))))
(shortcut :return (reduce (fn[a b] (if (> a 50000000) (:return a) (+ a b))) 0 (range)))
(last (take-while #(not= :done %) (reductions (fn[a b] (if (> a 50000000) :done (+ a b))) 0 (range))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.