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
