On Mon Apr 9 14:07 2012, Daniel Solano Gómez wrote: > On Mon Apr 9 18:54 2012, Tassilo Horn wrote: > > To check that, I've created the simple benchmark below that runs the > > current and enhanced implementation 10 million times with a evenly > > distributed set of numbers, Booleans "created properly" with valueOf(), > > Booleans created with the constructor, Strings, and nulls. > > > > To my amazement, the variant that explicitly checks for Boolean wrapper > > objects is not at all slower. On my machine with IcedTea7-2.1, the 10 > > million checks with either the current null/false-check or the > > null/false/Boolean-check take about 155 milliseconds. > > > > So at least from a performance standpoint, there doesn't seem to be a > > reason not to do it. It's just a semantic question: should > > (Boolean. false) bo a truthy thing? Right now, it is and the docs state > > that. But is that good, especially since this topic pops up every few > > months on the list? And equally important: is there existing code that > > relies on (Boolean. false) being truthy? > > Unfortunately, your methodology is flawed. The overhead of iterating > through a list and converting the ints into objects is obscuring the > perfomance difference between the two. > > Running a modified version of the code (attached) using an instrumenting > profiler shows that the version that checks for the Boolean instance is > about 6% slower than the version that does not. > > In any case, these are somewhat meaningless micro-benchmarks. > Ultimately, whether or not Clojure’s if should handle (Boolean. false) > is more of a design/philosophical question.
First, I forgot to attach the revised code. Second, I revised my code yet again and ran it outside the profiler. I am finding that eval2 is at least an order of magnitude slower, somewhere around 20×. Sincerely, Daniel
public class IfTest { static final Object True = new Object(); static final Object False = new Object(); public static Object eval(Object t) { if ((t != null) && (t != Boolean.FALSE)) { return True; } return False; } public static Object eval2(Object t) { if (((t != null) && (t != Boolean.FALSE)) || ((t instanceof Boolean) && ((Boolean) t).booleanValue())) { return True; } return False; } public static void main(String[] args) { int MAX = 10000000; Object[] l = new Object[MAX]; for (int i = 0; i < MAX; i++) { double d = Math.random(); if (d < 0.2) { l[i] = i; } else if (d < 0.4) { l[i] = Boolean.valueOf(Math.random() < 0.5 ? true : false); } else if (d < 0.6) { l[i] = new Boolean(Math.random() < 0.5 ? true : false); } else if (d < 0.8) { l[i] = String.valueOf(i * i * i); } else { l[i] = null; } } // For warmup... for (Object o :l) { if (eval(o) != eval2(o)) { throw new RuntimeException(); } } long time = System.nanoTime(); for (Object o : l) { eval(o); } long time2 = System.nanoTime() - time; System.out.println("eval(): " + (time2/1000.0) + "μs"); time = System.nanoTime(); for (Object o : l) { eval2(o); } time2 = System.nanoTime() - time; System.out.println("eval2(): " + (time2/1000.0) + "μs"); } }
signature.asc
Description: Digital signature