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");
        }
}

Attachment: signature.asc
Description: Digital signature

Reply via email to