Skip to content

Instantly share code, notes, and snippets.

@erluko
Created November 19, 2011 23:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erluko/1379512 to your computer and use it in GitHub Desktop.
Save erluko/1379512 to your computer and use it in GitHub Desktop.
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