Home

Primitives vs. Autoboxing Speed Test

Posted on May 27th, 2007 in The Art of Computer Programming by Jorge Luis

What executes faster, a calculation involving unwrapped primitives or one that uses autoboxed values? The answer is not as straight-forward as you might expect.

A quick review.

Autoboxing is the automatic wrapping of primitive values into their object-oriented class wrappers, a convenience feature introduced with Java 5. So, whereas before Java 5, you’d have to write code such as this
Double pi = new Double(3.14);
with autoboxing, the wrapping of a double primitive into its wrapper class (right-hand side) is done for you, i.e.,
Double pi = 3.14;
is equivalent to the above expression.

However, in this expression
double pi = 3.14;
the right hand side remains a primitive double.

Autounboxing is also provided, converting a wrapped value into its primitive form.
double pi = new Double(3.14);
A hypothesis

Since autoboxed expressions imply the creation of an object behind the scenes, you might expect that the overhead of object creation would make them execute more slowly than expressions involving primitive values only. In fact, chapter 1 of Java 2 v5.0 Tiger New Features warns that abusing the autoboxing feature can lead to performance degradation. A simple unit test should demonstrate this expectation.

We will race two implementations of the hypotenuse formula, one implemented with primitive doubles, the other with autoboxed doubles:

package com.jluix.lab.unit.learning.autoboxing;

public class AutoboxDouble
    {
    public double hypotenusePrimitive()
        {
        return Math.sqrt(this.a * this.a + this.b * this.b);
        }

    public Double hypotenuseBoxed()
        {
        return Math.sqrt(this.aBoxed * this.aBoxed + this.bBoxed * this.bBoxed);
        }

    public AutoboxDouble(double a, double b)
        {
        this.a = a;
        this.b = b;
        this.aBoxed = a;
        this.bBoxed = b;
        }

    private double a;
    private double b;
    private Double aBoxed;
    private Double bBoxed;
    }

The signature for Math.sqrt is public double java.lang.Math.sqrt(double value). It takes and returns a primitive double. That means hypotenuseBoxed involves both autounboxing and autoboxing.

The expression

this.aBoxed*this.aBoxed + this.bBoxed*this.bBoxed

has to evaluate to a primitive double. So the wrapped Double aBoxed and Double aBoxed are coverted to their primitive forms. Furthermore, since hypotenuseBoxed() returns Double, the primitive value returned by

return Math.sqrt(this.aBoxed*this.aBoxed + this.bBoxed*this.bBoxed);

is autoboxed into its wrapper form. If all goes well, this should turn out to be a pretty inefficient implementation of the hypotenuse formula.

double hypotenuseUnboxed() involves nothing but simple primitive doubles and does not carry any object-creation overhead, theoretically making it faster than its autoboxing counterpart.

Off to the races!

The following unit test executes both hypotenuse calculations and compares their execution times, asserting that the primitive calculation should run faster.

package com.jluix.lab.unit.learning.autoboxing;

import junit.framework.TestCase;

/**
 * Demonstrates autoboxing and autounboxing doubles.
 * Based on discussion in ch 1 of Java 2 v5.0 Tiger New Features, by Herber Schildt
 */
public class TestAutoboxDouble extends TestCase
    {
    /**
     * Executes autoboxed/autounboxed and primitive-only calculations and compares their execution times.
     */
    public void testPrimitivesFasterThanAutoboxedWrappers()
        {
        long boxedTime     = runBoxed();
        long primitiveTime = runPrimitive();
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     * Executes hypotenuse implemntation that involves autoboxing and autounboxing the triangle sides.
     * @return execution time
     */
    private long runBoxed()
        {
        long startBoxed = System.nanoTime();
        this.autoboxDouble.hypotenuseBoxed();
        long boxedTime = System.nanoTime() - startBoxed;
        return boxedTime;
        }

    /**
     * Executes hypotenuse implementation that involves primitive double triangle sides.
     * @return execution time
     */
    private long runPrimitive()
        {
        long startPrimitive = System.nanoTime();
        this.autoboxDouble.hypotenusePrimitive();
        long primitiveTime = System.nanoTime() - startPrimitive;
        return primitiveTime;
        }

    /**
     * Asserts that the excecution time for an autoboxed/autounboxed calculation is slower than the execution time for
     * a calcuation involving primitives only.
     *
     * @param boxedTime execution time of autoboxed/autounboxed calculation
     * @param primitiveTime execution time of primitive calculation
     */
    private void assertRunTime(long boxedTime, long primitiveTime)
        {
        System.out.println("(boxed time: " + boxedTime + " ns), (primitive time: " + primitiveTime + " ns)");
        assertTrue("Autoboxed/unboxed calculation (" + boxedTime +
                   ") should run slower than purely primitive calculation (" + primitiveTime + ").",
                   primitiveTime < boxedTime);
        }

    public TestAutoboxDouble(String name)
        {
        super(name);
        }

    /**
     * Set up the fixture before every test method call.
     */
    protected void setUp() throws Exception
        {
        this.autoboxDouble = new AutoboxDouble(5,7);
        }

    /**
     * Tear down the fixture after every test method call.
     */
    protected void tearDown() throws Exception
        {
        this.autoboxDouble = null;
        }

    private AutoboxDouble autoboxDouble;
    }

As expected, the primitive calculation runs much faster than the autoboxed calculation, 15.5 times faster, 2000 ns and 31,000 ns, respectively.

Primitives faster than wrappers?

But of course, that’s not the end of the story. You may have noticed that the autoboxed calculation in this unit test runs before the primitive calculation.


long boxedTime = runBoxed();
long primitiveTime = runPrimitive();

What happens if we simply reverse the call order, as does the unit test below? Would you expect a different result? If you had to wager a guess, on which side would you bet?

   /**
     * Executes autoboxed/autounboxed and primitive-only calculations and compares their execution times.  Runs the
     * primitive calculation first.
     */
    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirst()
        {
        long primitiveTime = runPrimitive();
        long boxedTime     = runBoxed();
        assertRunTime(boxedTime, primitiveTime);
        }

Surprisingly, this simple change causes the autoboxed implementation to run faster, 4000 ns and 20,000 ns or 5 times faster. This happens consitently, test run after test run.

Primitives first

Perhaps the run-time is optimizing these almost identical implementations, maybe using the same bytecode for both. But that’s just a guess. If it were the case, you’d think the times would be identical.

To try and shed some light into this behavior, let’s see what happens when the primitive calculation is run again, a second time, as in

    /**
     * What's going on in testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirst?  Some sort of vm
     * optimization?
     */
    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRepeat()
        {
        long primitiveTime = runPrimitive();
        long boxedTime     = runBoxed();
             primitiveTime = runPrimitive();
        assertRunTime(boxedTime, primitiveTime);
        }

Once more, the primitive calculation wins out, consistently over many test runs.

primitiveboxedprimitive.jpg

So, what would happen if both calculations are executed multiple times in one test run? This test runs them 100 times and then compares their execution times.

 public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoop()
        {
        long primitiveTime = 0;
        long boxedTime   = 0;
        for (int i=0; i<100; i++)
            {
            primitiveTime = runPrimitive();
            boxedTime   = runBoxed();
            }
        assertRunTime(boxedTime, primitiveTime);
        }

Results vary over test runs. Here’s one sequence of 10 runs.

Run Boxed Time (ns) Primitive Time (ns)
1 1000 0
2 1000 0
3 1000 0
4 2000 0
5 1000 0
6 1000 1000
7 1000 0
8 1000 1000
9 1000 1000
10 1000 0

It looks like the vm may optimize, but not every time. The same time behavior occurs when the calculations are run using different triangle sides, as in

public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopDiffFixtures()
        {
        long primitiveTime = 0;
        long boxedTime     = 0;
        for (int i=0; i<100; i++)
            {
            primitiveTime = runPrimitive();
            boxedTime   = runBoxed();
            this.autoboxDouble = new AutoboxDouble(i*2, i*5);
            }
        assertRunTime(boxedTime, primitiveTime);
        }

Putting all these unit tests together, this is what it looks like when all unit tests are run.

All 1

All 2

All 3

All 4

If you repeat the tests enough times, you’ll see all combinations, primitive calculations taking less, the same, and more time than the autoboxed counterpart.

Conclusion

So what is the answer to the original question? Are primitives always faster than autoboxed values? This brief experiment demonstrates that a good deal of the time they are faster. However, the ultimate answer seems to depend on what optimizations the vm performs at run time.

Full source code

AutoboxDouble.java

package com.jluix.lab.unit.learning.autoboxing;

/**
 * User: jorge
 * Date: Apr 29, 2007
 * Time: 9:37:08 PM
 */
public class AutoboxDouble
    {
    public double hypotenusePrimitive()
        {
        return Math.sqrt(this.a * this.a + this.b * this.b);
        }

    public Double hypotenuseBoxed()
        {
        return Math.sqrt(this.aBoxed * this.aBoxed + this.bBoxed * this.bBoxed);
        }

    public AutoboxDouble(double a, double b)
        {
        this.a = a;
        this.b = b;
        this.aBoxed = a;
        this.bBoxed = b;
        }

    private double a;
    private double b;
    private Double aBoxed;
    private Double bBoxed;
    }

TestAutoboxDouble.java

/**
 * User: jorge
 * Date: Apr 29, 2007
 * Time: 9:35:35 PM
 */
package com.jluix.lab.unit.learning.autoboxing;

import junit.framework.TestCase;

/**
 * Demonstrates autoboxing and autounboxing doubles.
 * Based on discussion in ch 1 of Java 2 v5.0 Tiger New Features, by Herber Schildt
 */
public class TestAutoboxDouble extends TestCase
    {
    public TestAutoboxDouble(String name)
        {
        super(name);
        }

    /**
     * Set up the fixture before every test method call.
     */
    protected void setUp() throws Exception
        {
        this.autoboxDouble = new AutoboxDouble(5,7);
        }

    /**
     * Tear down the fixture after every test method call.
     */
    protected void tearDown() throws Exception
        {
        this.autoboxDouble = null;
        }

    /**
     * Executes autoboxed/autounboxed and primitive-only calculations and compares their execution times.  Runs the
     * primitive calculation first.
     */
    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirst()
        {
        long primitiveTime = runPrimitive();
        long boxedTime     = runBoxed();
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     * What's going on in testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirst?  Some sort of vm
     * optimization?
     */
    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRepeat()
        {
        long primitiveTime = runPrimitive();
        long boxedTime     = runBoxed();
             primitiveTime = runPrimitive();
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     *  What would happen if both calculations are executed multiple times in one test run?  This test runs them 100
     *  times then compares their execution times.
     */
    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoop()
        {
        long primitiveTime = 0;
        long boxedTime   = 0;
        for (int i=0; i<100; i++)
            {
            primitiveTime = runPrimitive();
            boxedTime   = runBoxed();
            }
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     *  What would happen if both calculations are executed multiple times in one test run using different fixtures?
     *  This test runs them 100 times, creating a different triangle each time, and then compares their execution times.
     */
    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopDiffFixtures()
        {
        long primitiveTime = 0;
        long boxedTime     = 0;
        for (int i=0; i<100; i++)
            {
            primitiveTime = runPrimitive();
            boxedTime   = runBoxed();
            this.autoboxDouble = new AutoboxDouble(i*2, i*5);
            }
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     * Executes autoboxed/autounboxed and primitive-only calculations and compares their execution times.
     */
    public void testPrimitivesFasterThanAutoboxedWrappersRunWrappersFirst()
        {
        long boxedTime     = runBoxed();
        long primitiveTime = runPrimitive();
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     * Executes hypotenuse implemntation that involves autoboxing and autounboxing the triangle sides.
     * @return execution time
     */
    private long runBoxed()
        {
        long startBoxed = System.nanoTime();
        this.autoboxDouble.hypotenuseBoxed();
        long boxedTime = System.nanoTime() - startBoxed;
        return boxedTime;
        }

    /**
     * Executes hypotenuse implementation that involves primitive double triangle sides.
     * @return execution time
     */
    private long runPrimitive()
        {
        long startPrimitive = System.nanoTime();
        this.autoboxDouble.hypotenusePrimitive();
        long primitiveTime = System.nanoTime() - startPrimitive;
        return primitiveTime;
        }

    /**
     * Asserts that the excecution time for an autoboxed/autounboxed calculation is slower than the execution time for
     * a calcuation involving primitives only.
     *
     * @param boxedTime execution time of autoboxed/autounboxed calculation
     * @param primitiveTime execution time of primitive calculation
     */
    private void assertRunTime(long boxedTime, long primitiveTime)
        {
        System.out.println("(boxed time: " + boxedTime + " ns), (primitive time: " + primitiveTime + " ns)");
        assertTrue("Autoboxed/unboxed calculation (" + boxedTime +
                   ") should run slower than purely primitive calculation (" + primitiveTime + ").",
                   primitiveTime < boxedTime);
        }

    private AutoboxDouble autoboxDouble;
    }

Refactored source code

AutoboxDouble.java

package com.jluix.lab.unit.learning.autoboxing;

/**
 * User: jorge
 * Date: Apr 29, 2007
 * Time: 9:37:08 PM
 */
public class AutoboxDouble
    {
    /**
     * Computes the hypotenuse of a right triangle.  Not a good control for comparing primitive vs. autoboxing
     * performance as it relies on the Math.sqrt function which very likely performs parameter-based caching.
     */
    public static final Command HYPOTENUSE_COMMAND = new Command()
    {

    public double computePrimitive(double a, double b)
        {
        return Math.sqrt(a * a + b * b);
        }

    public Double computeBoxed(Double a, Double b)
        {
        return Math.sqrt(a * a + b * b);
        }

    public String getName()
        {
        return "HYPOTENUSE";
        }
    };

    /**
     * Computes the area of a rectangle.  Less likely to involve paramter-based caching, but still a possiblity.
     */
    public static final Command RECTANGULAR_AREA_COMMAND = new Command()
    {

    public double computePrimitive(double a, double b)
        {
        return a * b;
        }

    public Double computeBoxed(Double a, Double b)
        {
        return a * b;
        }

    public String getName()
        {
        return "RECTANGULAR_AREA";
        }
    };

    /**
     * Simply returns one of the sides passed.  Any run-time optimization involved?  Probably not.
     */
    public static final Command SINGLE_SIDE_COMMAND = new Command()
    {

    public double computePrimitive(double a, double b)
        {
        return a;
        }

    public Double computeBoxed(Double a, Double b)
        {
        return (double) a;//unbox, then re-box
        }

    public String getName()
        {
        return "SINGLE_SIDE";
        }
    };

    public double computePrimitive()
        {
        return this.command.computePrimitive(this.a, this.b);
        }

    public Double computeBoxed()
        {
        return this.command.computeBoxed(this.aBoxed, this.bBoxed);
        }

    public String getCommandName()
        {
        return this.command.getName();
        }

    public AutoboxDouble(double a, double b, Command command)
        {
        if (command == null)
            {
            throw new IllegalArgumentException("command cannot be null.");
            }
        this.command = command;

        this.a = a;
        this.b = b;
        this.aBoxed = a;
        this.bBoxed = b;
        }

    private double a;
    private double b;
    private Double aBoxed;
    private Double bBoxed;
    private Command command;
    }

TestAutoboxDouble.java

/**
 * User: jorge
 * Date: Apr 29, 2007
 * Time: 9:35:35 PM
 */
package com.jluix.lab.unit.learning.autoboxing;

import junit.framework.TestCase;

/**
 * Demonstrates autoboxing and autounboxing doubles.
 * Based on discussion in ch 1 of Java 2 v5.0 Tiger New Features, by Herber Schildt
 */
public class TestAutoboxDouble extends TestCase
    {
    public TestAutoboxDouble(String name)
        {
        super(name);
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstHypotenuse()
        {
        this._setUp(AutoboxDouble.HYPOTENUSE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirst();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRepeatHypotenuse()
        {
        this._setUp(AutoboxDouble.HYPOTENUSE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRepeat();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopHypotenuse()
        {
        this._setUp(AutoboxDouble.HYPOTENUSE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoop();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopDiffFixturesHypotenuse()
        {
        this._setUp(AutoboxDouble.HYPOTENUSE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopDiffFixtures();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstAvoidArgCachingHypotenuse()
        {
        this._setUp(AutoboxDouble.HYPOTENUSE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstAvoidArgCaching();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunWrappersFirstHypotenuse()
        {
        this._setUp(AutoboxDouble.HYPOTENUSE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunWrappersFirst();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRectangularArea()
        {
        this._setUp(AutoboxDouble.RECTANGULAR_AREA_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirst();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRepeatRectangularArea()
        {
        this._setUp(AutoboxDouble.RECTANGULAR_AREA_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRepeat();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopRectangularArea()
        {
        this._setUp(AutoboxDouble.RECTANGULAR_AREA_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoop();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopDiffFixturesRectangularArea()
        {
        this._setUp(AutoboxDouble.RECTANGULAR_AREA_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopDiffFixtures();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstAvoidArgCachingRectangularArea()
        {
        this._setUp(AutoboxDouble.RECTANGULAR_AREA_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstAvoidArgCaching();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunWrappersFirstRectangularArea()
        {
        this._setUp(AutoboxDouble.RECTANGULAR_AREA_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunWrappersFirst();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstSingleSide()
        {
        this._setUp(AutoboxDouble.SINGLE_SIDE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirst();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRepeatSingleSide()
        {
        this._setUp(AutoboxDouble.SINGLE_SIDE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRepeat();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopSingleSide()
        {
        this._setUp(AutoboxDouble.SINGLE_SIDE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoop();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopDiffFixturesSingleSide()
        {
        this._setUp(AutoboxDouble.SINGLE_SIDE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopDiffFixtures();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstAvoidArgCachingSingleSide()
        {
        this._setUp(AutoboxDouble.SINGLE_SIDE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstAvoidArgCaching();
        }

    public void testPrimitivesFasterThanAutoboxedWrappersRunWrappersFirstSingleSide()
        {
        this._setUp(AutoboxDouble.SINGLE_SIDE_COMMAND);
        this._testPrimitivesFasterThanAutoboxedWrappersRunWrappersFirst();
        }

    /**
     * Tear down the fixture after every test method call.
     */
    protected void tearDown()
        {
        this.autoboxDouble = null;
        this.command = null;
        }

    /**
     * Set up the fixture before every test method call.
     */
    private void _setUp(Command command)
        {
        this.a = 5;
        this.b = 7;
        this.command = command;
        this.autoboxDouble = new AutoboxDouble(this.a, this.b, this.command);
        }

    /**
     * Executes autoboxed/autounboxed and primitive-only calculations and compares their execution times.  Runs the
     * primitive calculation first.
     */
    private void _testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirst()
        {
        long primitiveTime = runPrimitive();
        long boxedTime = runBoxed();
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     * What's going on in testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirst?  Some sort of vm
     * optimization?
     */
    private void _testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstRepeat()
        {
        long primitiveTime = runPrimitive();
        long boxedTime = runBoxed();
        primitiveTime = runPrimitive();
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     * What would happen if both calculations are executed multiple times in one test run?  This test runs them 100
     * times then compares their execution times.
     */
    private void _testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoop()
        {
        long primitiveTime = 0;
        long boxedTime = 0;
        for (int i = 0; i < 100; i++)
            {
            primitiveTime = runPrimitive();
            boxedTime = runBoxed();
            }
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     * What would happen if both calculations are executed multiple times in one test run using different fixtures?
     * This test runs them 100 times, creating a different triangle each time, and then compares their execution times.
     */
    private void _testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstLoopDiffFixtures()
        {
        long primitiveTime = 0;
        long boxedTime = 0;
        this.autoboxDouble = new AutoboxDouble(this.a, this.b, this.command);
        for (int i = 0; i < 100; i++)
            {
            primitiveTime = runPrimitive();
            boxedTime = runBoxed();
            this.autoboxDouble = new AutoboxDouble(i * 2, i * 5, this.command);
            }
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     * Avoid possible argument-based caching by providing each implemenation with different arguments.
     */
    private void _testPrimitivesFasterThanAutoboxedWrappersRunPrimitivesFirstAvoidArgCaching()
        {
        long primitiveTime = 0;
        long boxedTime = 0;
        for (int i = 0; i < 100; i++)
            {
            this.autoboxDouble = new AutoboxDouble(i * 2, i * 5, this.command);
            primitiveTime = runPrimitive();
            this.autoboxDouble = new AutoboxDouble(i * 7, i * 4, this.command);
            boxedTime = runBoxed();
            assertRunTime(boxedTime, primitiveTime);
            }
        }

    /**
     * Executes autoboxed/autounboxed and primitive-only calculations and compares their execution times.
     */
    private void _testPrimitivesFasterThanAutoboxedWrappersRunWrappersFirst()
        {
        long boxedTime = runBoxed();
        long primitiveTime = runPrimitive();
        assertRunTime(boxedTime, primitiveTime);
        }

    /**
     * Executes calculation implementation that involves autoboxing and autounboxing the triangle sides.
     *
     * @return execution time
     */
    private long runBoxed()
        {
        long startBoxed = System.nanoTime();
        this.autoboxDouble.computeBoxed();
        long boxedTime = System.nanoTime() - startBoxed;
        return boxedTime;
        }

    /**
     * Executes calculation implementation that involves primitive double triangle sides.
     *
     * @return execution time
     */
    private long runPrimitive()
        {
        long startPrimitive = System.nanoTime();
        this.autoboxDouble.computePrimitive();
        long primitiveTime = System.nanoTime() - startPrimitive;
        return primitiveTime;
        }

    /**
     * Asserts that the excecution time for an autoboxed/autounboxed calculation is slower than the execution time for
     * a calcuation involving primitives only.
     *
     * @param boxedTime     execution time of autoboxed/autounboxed calculation
     * @param primitiveTime execution time of primitive calculation
     */
    private void assertRunTime(long boxedTime, long primitiveTime)
        {
        System.out.println(this.autoboxDouble.getCommandName() + " (boxed time: " + boxedTime + " ns), (primitive time: " + primitiveTime + " ns)");
        assertTrue("Autoboxed/unboxed calculation (" + boxedTime + ") should run slower than purely primitive calculation (" + primitiveTime + ").", primitiveTime < boxedTime);
        }

    private double a;
    private double b;
    private AutoboxDouble autoboxDouble;
    private Command command;
    }

Command.java

package com.jluix.lab.unit.learning.autoboxing;

/**
 * Provide two implementations of the same calculation, one involving primitives and the other autoboxing/autounboxing.
 *
 * @author jorge
 * @version $Revision:  $
 * @created May 29, 2007 9:14:36 PM
 * @since 1.0
 */
public interface Command
    {
    double computePrimitive(double a, double b);

    Double computeBoxed(Double a, Double b);

    String getName();
    }

1st BUCL.org Campaign Launches

Posted on May 19th, 2007 in Cuba, Human Rights by Jorge Luis

Bloggers United for Cuban Liberty (BUCL.org) is a confederation of blogs and web sites that pool resources and ideas for use in campaigns that raise awareness of the Cuban reality. The first campaign focuses on Spain’s support of castro’s apartheid regime, a system I personally experienced and witnessed as a child in Cuba. When my grandfather visited us as part of “la comunidad”, exile community, I distinctly remember getting a momentary glimpse at how the other half lives in Cuba. We were allowed to accompany him into his tourist-only hotel and to a tourist-only store to buy necessities rationed or completely unvailable to the general Cuban population.
But the Cuban apartheid system not only bifurcates regular citizens and tourists, but Cubans themselves, along political lines. You either support the one-party state or you don’t. In the latter case, you are resigned to a marginal existence. My father was one such persona non grata, having been incarcerated for denouncing the regime during his days at CMQ, the broadcasting company where he worked as a director and writer. While serving guard duty, he wrote in the back of studio entry passes, “Down with the Revolution” or something to that effect. For that, he served three years in prison, and could never work in tv again. Talk about being black-listed.

This picture says it all, disenfranchised Cuban’s Cuba on the left, tourists’ and upper class’ Cuba on the right.

Two Cubas

Bloggers at Cuba Nostalgia

Posted on May 19th, 2007 in Cuba by Jorge Luis

I write this literally to the beat of a conga drum, blogging live from Cuba Nostalgia, as a comparsa circles the venue. I came to meet and support the people behind Babalublog, who’ve set up a booth here. This is yet another ironic instance of the internet bringing together people that would likely not have met in person otherwise.

It’s my second time at Cuba Nostalgia, which I attended a few years ago when it was held in Coconut Grove. It seems twice as big now, a Cuban neutrino star, densely packed with the sights, sounds, smells, tastes, and memories of Cuba, a little bit of heaven in Miami.

cubanostalgia2007.jpg

Docuspintary

Posted on May 19th, 2007 in Cuba by Jorge Luis

docuspintary - n. (pl. -ries) a movie or a television or a radio program that provides an intentionally distorted record or report.

docuspintarist - n. One who produces docuspintaries. See Michael Moore, modern master of the docuspintary form. He spins innocent facts beyond recognition into effective, wool-over-their-eyes, demagogic propaganda.

Centrally Planned Poverty

Posted on May 6th, 2007 in Cuba, Human Rights by Jorge Luis

What ails the Cuban economy? It ain’t the American embargo, folks. It’s, as Fred Thompson aptly puts it, “centrally planned poverty.”

One point he fails to make in his excellent piece on Cuban socialized health care, or the lack thereof, is that it really isn’t free. Cubans pay for it with their forced labor, during high school with forced agricultural work, thereafter with indentured servitude to foreign companies, and with their forced forfeiture of freedom, to name just a few obvious examples. The American army advertises that freedom isn’t free. Well, neither is Cuban socialized health care, which Cubans pay for in the currency of liberty.

Update: Babalublog today has an excellent blogosphere roundup on the Cuban health care system.

A Twist on Reclaiming Property castro Stole

Posted on May 2nd, 2007 in Cuba by Jorge Luis

The exile community’s motivation for wanting regime change in Cuba is often maligned as a revengeful, avaricious greed that hungers to take back the property the revolution stole from us. Here’s a case in point. As an attack on the exiles, the issue is framed as an us vs. them scenario, the impoverished Cubans back home vs. the ruthless exiles. The truth of the matter is that hardly anyone, though justified, intends to reclaim property, the main reason being that too much time has passed, too much has been destroyed, and too many lives have been rebuilt in exile.

But it turns out that there’s yet another group of Cubans that also have a rightful claim to their stolen property, namely, the subset that remains in Cuba, that never left. It never had occurred to me that there would still be people in Cuba who had endured the same fate in the early ’60’s, or their children. So, it took me by surprise when a friend that recently left revealed her family owns a large apartment in El Vedado in a building they originally owned but that the revolution confiscated. So, I asked her if she or her family, who are still in Cuba, wanted to reclaim it when things change. She answered no. Again, two much time has passed. The two units above have long since changed owners numerous times. To attempt such a thing would be an accounting nightmare, if not an impossibility.

The complete picture is not as simple as an us vs. them situation. It’s not the exile community against Cubans in Cuba. It’s simply a Cuban problem, which includes all of us. But, for the record, I’m not going to attempt to regain my grandfather’s restaurant either, which probably doesn’t even exist anymore. So, borron y cuenta nueva. The civilization to which those claims belong has gone with the wind.

Web Mob

Posted on May 2nd, 2007 in The Art of Computer Programming by Jorge Luis

This may be a first for the web, the first cyber-riot. The digg.com community revolted when the site operators deleted a story revealing the decoding key for HD-DVD. So, all it takes for a “web 2.0″ community to become a “web 2.0″ mob is for the community to vociferously complain?

A Modest Proposal for Dismantling the Cuban Embargo

Posted on May 1st, 2007 in Cuba, Human Rights by Jorge Luis

This is a step-by-step proposal for removing the embargo on Cuba.

  1. Remove the Cuban government’s embargo on the free exercise of religion.
  2. Remove the Cuban government’s embargo on freedom of speech.
  3. Remove the Cuban government’s embargo on freedom of the press.
  4. Remove the Cuban government’s embargo on the right of the people to peaceably assemble.
  5. Remove the Cuban government’s embargo on the right of the people to petition the government for a redress of grievances.
  6. Remove the Cuban government’s embargo on the right of the people to keep and bear arms.
  7. Remove the Cuban government’s embargo on the right of the people to be secure in their persons, houses, papers, and effects, against unreasonable searches and seizures.
  8. Remove the Cuban government’s embargo on the right of the people to a speedy and public trial by a jury of their peers.
  9. Remove the Cuban government’s embargo on the right of the people to be free from excessive bail, excessive fines, and cruel and unusual punishments.

That would be a good start.