Skip to content

Instantly share code, notes, and snippets.

@mfikes
Last active September 20, 2018 03:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mfikes/0c346d84c5f5cfd9d41d8469729ec177 to your computer and use it in GitHub Desktop.
Save mfikes/0c346d84c5f5cfd9d41d8469729ec177 to your computer and use it in GitHub Desktop.
Negative Benchmark

If you run a trivial benchmark that can be heavily optimized, such as

(simple-benchmark [] 1 1)

You can sometimes see negative benchmarks under :advanced such as

[], 1, 1 runs, -2 msecs

In this case, you end up with heavily elided JavaScript code, as if it were effectively produced from ClojureScript like the following (measuring the elapsed time to do nothing):

(let [start (.getTime (js/Date.))
      end   (.getTime (js/Date.))]
    (- end start))

Ignoring simple-benchmark and what :advanced does with the code generated for it, let's say you actually start with the above code. This gets transpiled by ClojureScript to the following, which is fine:

(function() {
  var start = new Date().getTime();
  var end = new Date().getTime();
  return end - start;
})();

But then Closure :advanced performs an overly aggressive inlining optimization of the date expressions, producing

(new Date).getTime()-(new Date).getTime()

Given the left-to-right evaluation order, the number on the right can be larger (if, for example, evaluated a couple of milliseconds later), thus producing a negative number.

I've written google/closure-compiler#3079

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment