Note that there are some explanatory texts on larger screens.

plurals
  1. POjava immutable class much slower
    primarykey
    data
    text
    <p>I was in need of some Complex math library, so I hesitated between libraries that use immutable Complex and libraries that use mutable Complex. Obviously, I want computations to run reasonably fast (unless it kills readability etc.).</p> <p>So I created simple test of speed mutable vs immutable:</p> <pre><code>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; } } final class ImmutableInt { private final int value; public ImmutableInt(int value) { this.value = value; } public int getValue() { return value; } } public class TestImmutableSpeed { static long testMutable(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(); } return sumMutable; } static long testImmutable(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(); } return sumImmutable; } public static void main(String[] args) { final int arrLen = 1&lt;&lt;14; long tmStart = System.nanoTime(); System.out.println("sum = " + testMutable(arrLen)); long tmMid = System.nanoTime(); System.out.println("sum = " + testImmutable(arrLen)); long tmEnd = System.nanoTime(); System.out.println("speed comparison mutable vs immutable:"); System.out.println("mutable " + (tmMid - tmStart)/1000000 + " ms"); System.out.println("immutable " + (tmEnd - tmMid)/1000000 + " ms"); } } </code></pre> <p>You can adjust size of array if the test runs too slow/fast.</p> <p>I run with: -server -Xms256m -XX:+AggressiveOpts And I get:</p> <pre>sum = 2199023247360 sum = 2199023247360 speed comparison mutable vs immutable: <b>mutable 102 ms immutable 1506 ms</b></pre> <p>Question: Am I missing some optimization parameter, or is immutable version 15x slower?</p> <p>If it is, why would anyone write math library with immutable class Complex in it? Is immutable just "fancy" but useless? </p> <p>I know that immutable class is safer as hash map key or can't have race conditions, but that are special cases that can be handled without immutability everywhere.</p> <p><strong>Edit:</strong> I re-run this microbenchmark with caliper, as suggested by one answer, and it runs 12x slower, not 15x, still the same point. Changed code for Caliper benchmarking:</p> <pre> import com.google.caliper.Runner; import com.google.caliper.SimpleBenchmark; 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; } } final class ImmutableInt { private final int value; public ImmutableInt(int value) { this.value = value; } public int getValue() { return value; } } public class TestImmutableSpeed extends SimpleBenchmark { static long testMutable(final int arrLen) { MutableInt[] arrMutable = new MutableInt[arrLen]; for (int i = 0; i </pre> <p>Output of Caliper:</p> <pre> 0% Scenario{vm=java, trial=0, benchmark=Mutable, type=-server, minMemory=-Xms256m, optimizations=-XX:+AggressiveOpts} 91614044.60 ns; ?=250338.20 ns @ 3 trials 50% Scenario{vm=java, trial=0, benchmark=Immutable, type=-server, minMemory=-Xms256m, optimizations=-XX:+AggressiveOpts} 1108057922.00 ns; ?=3920760.98 ns @ 3 trials benchmark ms linear runtime Mutable 91.6 == Immutable 1108.1 ============================== </pre> <p>Note that without the optimization parameters for JVM output of Caliper is:</p> <pre> 0% Scenario{vm=java, trial=0, benchmark=Mutable} 516562214.00 ns; ?=623120.57 ns @ 3 trials 50% Scenario{vm=java, trial=0, benchmark=Immutable} 1706758503.00 ns; ?=5842389.60 ns @ 3 trials benchmark ms linear runtime Mutable 517 ========= Immutable 1707 ============================== </pre> <p>So bad parameters make both version slow, but ratio is less terrible (but not important, still).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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