Java SynchronizedRandomAccessList vs CopyOnWriteArrayList

Here’s a microbenchmark of SynchronizedRandomAccessList and CopyOnWriteArrayList. I wanted to see how well one or another performed with little number of changed, where CopyOnWriteArrayList could potentially be better.

package com.icyrock.java.collection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;

public class SpeedPrb {
  private static interface ListCreator<I> {
    List<Integer> create(List<Integer> seed);
  }

  public static void main(String[] args) {
    new SpeedPrb().run();
  }

  private void run() {
    try {
      runUnsafe();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private void runUnsafe() throws InterruptedException {
    for (String runType : new String[] { "warm-up", "test" }) {
      System.out.println("Run type: " + runType);

      withList(new ListCreator<List<Integer>>() {
        public List<Integer> create(List<Integer> seed) {
          return Collections.synchronizedList(new ArrayList<Integer>(seed));
        }
      });

      withList(new ListCreator<List<Integer>>() {
        public List<Integer> create(List<Integer> seed) {
          return new CopyOnWriteArrayList<Integer>(seed);
        }
      });
    }
  }

  private void withList(ListCreator<List<Integer>> listCreator) throws InterruptedException {
    withThreadCount(listCreator, 1);
    withThreadCount(listCreator, 5);
    withThreadCount(listCreator, 10);
  }

  private void withThreadCount(ListCreator<List<Integer>> listCreator, int threadCount)
    throws InterruptedException {
    withDataSize(listCreator, threadCount, 10000);
    withDataSize(listCreator, threadCount, 100000);
    withDataSize(listCreator, threadCount, 1000000);
  }

  private void withDataSize(ListCreator<List<Integer>> listCreator, int threadCount, int dataSize)
    throws InterruptedException {
    withDataModSize(listCreator, threadCount, dataSize, 0);
    withDataModSize(listCreator, threadCount, dataSize, 1);
    withDataModSize(listCreator, threadCount, dataSize, 5);
    withDataModSize(listCreator, threadCount, dataSize, 10);
    withDataModSize(listCreator, threadCount, dataSize, 50);
  }

  private void withDataModSize(final ListCreator<List<Integer>> listCreator,
    final int threadCount, final int dataSize, final int dataModSize) throws InterruptedException {
    List<Integer> seed = new ArrayList<>();
    for (int i = 0; i < dataSize; i++) {
      seed.add(i);
    }

    List<Integer> list = listCreator.create(seed);

    long start = System.nanoTime();

    doMods(list, threadCount, dataSize, dataModSize);
    long sum = doSum(list, threadCount, dataSize);

    long end = System.nanoTime();
    double elapsed = (end - start) / 1e6;

    System.out.println("End"
      + ": list.class: " + list.getClass().getSimpleName()
      + ", threadCount: " + threadCount
      + ", dataSize: " + dataSize
      + ", dataModSize: " + dataModSize
      + ", elapsed: " + elapsed
      + ", sum: " + sum);
  }

  private void doMods(final List<Integer> list, final int threadCount, final int dataSize,
    final int dataModSize) throws InterruptedException {
    Thread[] threads = new Thread[threadCount];
    final int count = dataSize / threadCount;
    for (int i = 0; i < threadCount; i++) {
      final int modId = i * count;

      Thread thread = new Thread(new Runnable() {
        public void run() {
          int modCnt = 0;
          for (int i = 0; i < count; i++) {
            if (modCnt < dataModSize) {
              int pos = list.get(modId + i);
              list.set(pos, list.get(pos) + 1);
              modCnt++;
            }
            if (modCnt == dataModSize) {
              break;
            }
          }
        }
      });
      thread.setDaemon(true);

      threads[i] = thread;
    }

    for (int i = 0; i < threadCount; i++) {
      threads[i].start();
    }

    for (int i = 0; i < threadCount; i++) {
      Thread thread = threads[i];
      synchronized (thread) {
        if (thread.isAlive()) {
          thread.wait();
        }
      }
    }
  }

  private long doSum(final List<Integer> list, final int threadCount, final int dataSize)
    throws InterruptedException {
    final AtomicLong sum = new AtomicLong();

    Thread[] threads = new Thread[threadCount];
    final int count = dataSize / threadCount;
    for (int i = 0; i < threadCount; i++) {
      final int modId = i * count;

      Thread thread = new Thread(new Runnable() {
        public void run() {
          for (int i = 0; i < count; i++) {
            int pos = list.get(modId + i);
            long delta = list.get(pos);
            sum.addAndGet(delta);
          }
        }
      });
      thread.setDaemon(true);

      threads[i] = thread;
    }

    for (int i = 0; i < threadCount; i++) {
      threads[i].start();
    }

    for (int i = 0; i < threadCount; i++) {
      Thread thread = threads[i];
      synchronized (thread) {
        if (thread.isAlive()) {
          thread.wait();
        }
      }
    }

    return sum.get();
  }
}

Results:

Run type: warm-up
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 0, elapsed: 34.447801, sum: 49995000
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 1, elapsed: 8.95851, sum: 49995001
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 5, elapsed: 9.545876, sum: 49995009
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 10, elapsed: 1.744018, sum: 49995019
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 50, elapsed: 1.887545, sum: 49995099
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 0, elapsed: 10.752156, sum: 4999950000
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 1, elapsed: 13.370241, sum: 4999950001
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 5, elapsed: 15.297022, sum: 4999950009
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 10, elapsed: 10.267383, sum: 4999950019
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 50, elapsed: 16.844115, sum: 4999950099
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 0, elapsed: 74.83112, sum: 499999500000
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 1, elapsed: 82.226897, sum: 499999500001
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 5, elapsed: 74.646764, sum: 499999500009
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 10, elapsed: 71.52722, sum: 499999500019
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 50, elapsed: 73.328613, sum: 499999500099
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 0, elapsed: 7.449299, sum: 49995000
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 1, elapsed: 7.883584, sum: 49995005
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 5, elapsed: 7.536815, sum: 49995045
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 10, elapsed: 7.7768, sum: 49995095
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 50, elapsed: 9.246285, sum: 49995495
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 0, elapsed: 67.314426, sum: 4999950000
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 1, elapsed: 70.664588, sum: 4999950005
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 5, elapsed: 68.318753, sum: 4999950045
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 10, elapsed: 71.206388, sum: 4999950095
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 50, elapsed: 65.248959, sum: 4999950495
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 0, elapsed: 461.098965, sum: 499999500000
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 1, elapsed: 406.9108, sum: 499999500005
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 5, elapsed: 513.206703, sum: 499999500045
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 10, elapsed: 473.542246, sum: 499999500095
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 50, elapsed: 570.581461, sum: 499999500495
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 0, elapsed: 12.406631, sum: 49995000
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 1, elapsed: 14.833395, sum: 49995010
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 5, elapsed: 11.98533, sum: 49995090
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 10, elapsed: 11.679525, sum: 49995190
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 50, elapsed: 13.218288, sum: 49995990
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 0, elapsed: 69.624681, sum: 4999950000
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 1, elapsed: 69.140069, sum: 4999950010
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 5, elapsed: 77.640096, sum: 4999950090
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 10, elapsed: 71.927987, sum: 4999950190
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 50, elapsed: 66.570783, sum: 4999950990
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 0, elapsed: 378.502667, sum: 499999500000
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 1, elapsed: 419.156151, sum: 499999500010
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 5, elapsed: 339.901594, sum: 499999500090
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 10, elapsed: 426.555234, sum: 499999500190
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 50, elapsed: 395.766989, sum: 499999500990
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 0, elapsed: 11.901218, sum: 49995000
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 1, elapsed: 3.829014, sum: 49995001
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 5, elapsed: 10.980387, sum: 49995009
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 10, elapsed: 1.90118, sum: 49995019
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 50, elapsed: 5.033604, sum: 49995099
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 0, elapsed: 4.303462, sum: 4999950000
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 1, elapsed: 6.433356, sum: 4999950001
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 5, elapsed: 8.015953, sum: 4999950009
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 10, elapsed: 10.697569, sum: 4999950019
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 50, elapsed: 20.900689, sum: 4999950099
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 0, elapsed: 22.107373, sum: 499999500000
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 1, elapsed: 26.153887, sum: 499999500001
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 5, elapsed: 34.408805, sum: 499999500009
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 10, elapsed: 51.090004, sum: 499999500019
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 50, elapsed: 153.929584, sum: 499999500099
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 0, elapsed: 3.918603, sum: 49995000
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 1, elapsed: 5.118304, sum: 49995005
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 5, elapsed: 8.821934, sum: 49995045
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 10, elapsed: 12.317311, sum: 49995095
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 50, elapsed: 21.752215, sum: 49995495
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 0, elapsed: 40.760553, sum: 4999950000
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 1, elapsed: 27.017787, sum: 4999950005
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 5, elapsed: 24.395766, sum: 4999950045
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 10, elapsed: 39.489004, sum: 4999950095
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 50, elapsed: 113.153861, sum: 4999950495
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 0, elapsed: 353.752201, sum: 499999500000
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 1, elapsed: 282.50961, sum: 499999500005
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 5, elapsed: 423.664369, sum: 499999500045
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 10, elapsed: 501.767616, sum: 499999500095
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 50, elapsed: 1458.115879, sum: 499999500495
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 0, elapsed: 6.227392, sum: 49995000
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 1, elapsed: 27.889835, sum: 49995010
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 5, elapsed: 5.488267, sum: 49995090
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 10, elapsed: 9.8526, sum: 49995190
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 50, elapsed: 34.633951, sum: 49995990
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 0, elapsed: 44.695707, sum: 4999950000
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 1, elapsed: 21.955976, sum: 4999950010
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 5, elapsed: 54.120305, sum: 4999950090
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 10, elapsed: 78.413631, sum: 4999950190
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 50, elapsed: 239.205075, sum: 4999950990
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 0, elapsed: 362.92385, sum: 499999500000
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 1, elapsed: 320.027424, sum: 499999500010
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 5, elapsed: 505.38798, sum: 499999500090
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 10, elapsed: 1165.81135, sum: 499999500190
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 50, elapsed: 1869.912839, sum: 499999500990
Run type: test
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 0, elapsed: 0.97632, sum: 49995000
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 1, elapsed: 0.95858, sum: 49995001
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 5, elapsed: 0.979087, sum: 49995009
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 10, elapsed: 1.088347, sum: 49995019
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 50, elapsed: 1.278052, sum: 49995099
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 0, elapsed: 5.128055, sum: 4999950000
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 1, elapsed: 5.959685, sum: 4999950001
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 5, elapsed: 6.951121, sum: 4999950009
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 10, elapsed: 8.605555, sum: 4999950019
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 100000, dataModSize: 50, elapsed: 3.878474, sum: 4999950099
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 0, elapsed: 34.628495, sum: 499999500000
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 1, elapsed: 33.505706, sum: 499999500001
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 5, elapsed: 34.152629, sum: 499999500009
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 10, elapsed: 34.661612, sum: 499999500019
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 1000000, dataModSize: 50, elapsed: 33.869828, sum: 499999500099
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 0, elapsed: 7.829228, sum: 49995000
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 1, elapsed: 7.338248, sum: 49995005
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 5, elapsed: 6.597094, sum: 49995045
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 10, elapsed: 9.179939, sum: 49995095
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 10000, dataModSize: 50, elapsed: 12.672502, sum: 49995495
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 0, elapsed: 57.167164, sum: 4999950000
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 1, elapsed: 57.412349, sum: 4999950005
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 5, elapsed: 67.656372, sum: 4999950045
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 10, elapsed: 63.353544, sum: 4999950095
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 100000, dataModSize: 50, elapsed: 66.889391, sum: 4999950495
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 0, elapsed: 521.963095, sum: 499999500000
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 1, elapsed: 517.867147, sum: 499999500005
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 5, elapsed: 542.079316, sum: 499999500045
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 10, elapsed: 386.976245, sum: 499999500095
End: list.class: SynchronizedRandomAccessList, threadCount: 5, dataSize: 1000000, dataModSize: 50, elapsed: 405.384225, sum: 499999500495
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 0, elapsed: 8.967124, sum: 49995000
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 1, elapsed: 7.918772, sum: 49995010
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 5, elapsed: 4.081412, sum: 49995090
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 10, elapsed: 4.461432, sum: 49995190
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 50, elapsed: 6.415205, sum: 49995990
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 0, elapsed: 45.251236, sum: 4999950000
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 1, elapsed: 47.764752, sum: 4999950010
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 5, elapsed: 60.124809, sum: 4999950090
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 10, elapsed: 48.346995, sum: 4999950190
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 100000, dataModSize: 50, elapsed: 39.349112, sum: 4999950990
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 0, elapsed: 340.371111, sum: 499999500000
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 1, elapsed: 481.969672, sum: 499999500010
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 5, elapsed: 535.011974, sum: 499999500090
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 10, elapsed: 540.011967, sum: 499999500190
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 50, elapsed: 531.670146, sum: 499999500990
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 0, elapsed: 1.149342, sum: 49995000
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 1, elapsed: 1.239204, sum: 49995001
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 5, elapsed: 1.352173, sum: 49995009
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 10, elapsed: 1.7898, sum: 49995019
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 10000, dataModSize: 50, elapsed: 3.165936, sum: 49995099
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 0, elapsed: 5.357431, sum: 4999950000
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 1, elapsed: 6.688772, sum: 4999950001
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 5, elapsed: 8.353105, sum: 4999950009
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 10, elapsed: 10.515936, sum: 4999950019
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 100000, dataModSize: 50, elapsed: 20.277377, sum: 4999950099
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 0, elapsed: 23.185615, sum: 499999500000
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 1, elapsed: 27.466323, sum: 499999500001
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 5, elapsed: 33.748808, sum: 499999500009
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 10, elapsed: 48.301544, sum: 499999500019
End: list.class: CopyOnWriteArrayList, threadCount: 1, dataSize: 1000000, dataModSize: 50, elapsed: 198.997429, sum: 499999500099
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 0, elapsed: 5.603725, sum: 49995000
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 1, elapsed: 6.166289, sum: 49995005
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 5, elapsed: 7.827472, sum: 49995045
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 10, elapsed: 9.659996, sum: 49995095
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 10000, dataModSize: 50, elapsed: 20.942762, sum: 49995495
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 0, elapsed: 40.315674, sum: 4999950000
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 1, elapsed: 42.313047, sum: 4999950005
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 5, elapsed: 38.214826, sum: 4999950045
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 10, elapsed: 42.748483, sum: 4999950095
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 100000, dataModSize: 50, elapsed: 111.678623, sum: 4999950495
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 0, elapsed: 271.684979, sum: 499999500000
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 1, elapsed: 285.626939, sum: 499999500005
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 5, elapsed: 382.996082, sum: 499999500045
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 10, elapsed: 469.095528, sum: 499999500095
End: list.class: CopyOnWriteArrayList, threadCount: 5, dataSize: 1000000, dataModSize: 50, elapsed: 1126.529645, sum: 499999500495
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 0, elapsed: 5.903503, sum: 49995000
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 1, elapsed: 5.537715, sum: 49995010
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 5, elapsed: 8.679113, sum: 49995090
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 10, elapsed: 13.175054, sum: 49995190
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 50, elapsed: 27.420182, sum: 49995990
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 0, elapsed: 37.46934, sum: 4999950000
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 1, elapsed: 21.53966, sum: 4999950010
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 5, elapsed: 54.847308, sum: 4999950090
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 10, elapsed: 56.360711, sum: 4999950190
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 100000, dataModSize: 50, elapsed: 191.754104, sum: 4999950990
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 0, elapsed: 333.820706, sum: 499999500000
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 1, elapsed: 398.443131, sum: 499999500010
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 5, elapsed: 547.40548, sum: 499999500090
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 10, elapsed: 757.341745, sum: 499999500190
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 50, elapsed: 2268.404341, sum: 499999500990

This was done on AMD Phenom II X4 Mobile N950, 2.1 GHz, which has 4 cores.

Comments:

  • Modifications hurt CopyOnWriteArrayList, especially with big data sizes – even only 50 modifications make it 4 times slower
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 1000000, dataModSize: 50, elapsed: 531.670146, sum: 499999500990
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 1000000, dataModSize: 50, elapsed: 2268.404341, sum: 499999500990
  • Without modifications, SynchronizedRandomAccessList pays the price for having to do synchronization being 70%-80% slower:
End: list.class: SynchronizedRandomAccessList, threadCount: 10, dataSize: 10000, dataModSize: 0, elapsed: 8.967124, sum: 49995000
End: list.class: CopyOnWriteArrayList, threadCount: 10, dataSize: 10000, dataModSize: 0, elapsed: 5.903503, sum: 49995000
  • Warm-up is really important when measuring – here we see a 35 times slower run:
Run type: warm-up
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 0, elapsed: 34.447801, sum: 49995000
...
Run type: test
End: list.class: SynchronizedRandomAccessList, threadCount: 1, dataSize: 10000, dataModSize: 0, elapsed: 0.97632, sum: 49995000