Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is fascinating. Well, first of all, that is not a fair test; you aren't warming up the JVM when you do it that way. Benchmarking is typically very difficult to do. I refactored your code to use <a href="http://code.google.com/p/caliper/" rel="nofollow">Google Caliper</a>, and got similar, yet different results; the immutable class was only 3 times slower. Not sure why yet. Anyway here's the work so far:</p> <h2>TestImmutableSpeed.java</h2> <pre><code>import com.google.caliper.Runner; import com.google.caliper.SimpleBenchmark; public class TestImmutableSpeed { static final class MutableInt { private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } public MutableInt() { this(0); } public MutableInt(int value) { this.value = value; } } static final class ImmutableInt { private final int value; public ImmutableInt(int value) { this.value = value; } public int getValue() { return value; } } public static class TestBenchmark extends SimpleBenchmark { public void timeMutable(final int arrLen) { MutableInt[] arrMutable = new MutableInt[arrLen]; for (int i = 0; i &lt; arrMutable.length; ++i) { arrMutable[i] = new MutableInt(i); for (int j = 0; j &lt; arrMutable.length; ++j) { arrMutable[i].setValue(arrMutable[i].getValue() + j); } } long sumMutable = 0; for (MutableInt item : arrMutable) { sumMutable += item.getValue(); } System.out.println(sumMutable); } public void timeImmutable(final int arrLen) { ImmutableInt[] arrImmutable = new ImmutableInt[arrLen]; for (int i = 0; i &lt; arrImmutable.length; ++i) { arrImmutable[i] = new ImmutableInt(i); for (int j = 0; j &lt; arrImmutable.length; ++j) { arrImmutable[i] = new ImmutableInt(arrImmutable[i].getValue() + j); } } long sumImmutable = 0; for (ImmutableInt item : arrImmutable) { sumImmutable += item.getValue(); } System.out.println(sumImmutable); } } public static void main(String[] args) { Runner.main(TestBenchmark.class, new String[0]); } } </code></pre> <h2>Caliper Output</h2> <pre><code> 0% Scenario{vm=java, trial=0, benchmark=Immutable} 78574.05 ns; σ=21336.61 ns @ 10 trials 50% Scenario{vm=java, trial=0, benchmark=Mutable} 24956.94 ns; σ=7267.78 ns @ 10 trials benchmark us linear runtime Immutable 78.6 ============================== Mutable 25.0 ========= vm: java trial: 0 </code></pre> <h2>String update</h2> <p>So I was thinking about this more, and I decided to try changing the wrapped class from an <code>int</code> to an object, in this case a <code>String</code>. Changing the static classes to <code>String</code>s, and loading the strings with <code>Integer.valueOf(i).toString()</code>, and instead of adding, appending them in a <code>StringBuilder</code>, I got these results:</p> <pre><code> 0% Scenario{vm=java, trial=0, benchmark=Immutable} 11034616.91 ns; σ=7006742.43 ns @ 10 trials 50% Scenario{vm=java, trial=0, benchmark=Mutable} 9494963.68 ns; σ=6201410.87 ns @ 10 trials benchmark ms linear runtime Immutable 11.03 ============================== Mutable 9.49 ========================= vm: java trial: 0 </code></pre> <p>However, I think in this case the difference is dominated by all the array copying that would have to happen, and not the fact that it was using <code>String</code>s.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload