Skip to content

Instantly share code, notes, and snippets.

@simbo1905
Created November 10, 2014 17:42
Show Gist options
  • Save simbo1905/7a2404b8fe9e8b2488c8 to your computer and use it in GitHub Desktop.
Save simbo1905/7a2404b8fe9e8b2488c8 to your computer and use it in GitHub Desktop.
public class Runner01 {
static class Array1 {
private Object delegate;
private Object allocate(Object delegate, int[] is, int pos) {
if (pos < is.length) {
delegate = new Object[is[pos]];
for (int k = 0; k < is[pos]; ++k) {
((Object[]) delegate)[k] = allocate(((Object[]) delegate)[k], is, pos + 1);
}
}
return delegate;
}
private Object[] getArray(Object delegate, int i) {
Object[] subdelegate = (Object[]) delegate;
subdelegate = (Object[]) ((Object[]) subdelegate)[i];
return subdelegate;
}
private Object[] getArray(Object delegate, int i, int j) {
Object[] subdelegate = (Object[]) delegate;
subdelegate = (Object[]) ((Object[]) subdelegate)[i];
subdelegate = (Object[]) ((Object[]) subdelegate)[j];
return subdelegate;
}
private Object[] getArray(Object delegate, int i, int j, int k) {
Object[] subdelegate = (Object[]) delegate;
subdelegate = (Object[]) ((Object[]) subdelegate)[i];
subdelegate = (Object[]) ((Object[]) subdelegate)[j];
subdelegate = (Object[]) ((Object[]) subdelegate)[k];
return subdelegate;
}
private Object[] getArray(Object delegate, int i, int j, int k, int[] is) {
Object[] subdelegate = getArray(delegate, i, j, k);
for (int ii = 0; ii < is.length - 1; ++ii) {
subdelegate = (Object[]) ((Object[]) subdelegate)[is[ii]];
}
return subdelegate;
}
public Array1(int... is) {
delegate = allocate(delegate, is, 0);
}
public Double get(int i) {
Object[] subdelegate = (Object[]) delegate;
return (Double) subdelegate[i];
}
public Double get(int i, int j) {
Object[] subdelegate = getArray(delegate, i);
return (Double) subdelegate[j];
}
public Double get(int i, int j, int k) {
Object[] subdelegate = getArray(delegate, i, j);
return (Double) subdelegate[k];
}
public Double get(int i, int j, int k, int l) {
Object[] subdelegate = getArray(delegate, i, j, k);
return (Double) subdelegate[l];
}
public Double get(int i, int j, int k, int l, int... rest) {
Object[] subdelegate = getArray(delegate, i, j, k, rest);
return (Double) subdelegate[rest[rest.length - 1]];
}
public void set(Double value, int i) {
Object[] subdelegate = (Object[]) delegate;
subdelegate[i] = value;
}
public void set(Double value, int i, int j) {
Object[] subdelegate = getArray(delegate, i);
subdelegate[j] = value;
}
public void set(Double value, int i, int j, int k) {
Object[] subdelegate = getArray(delegate, i, j);
subdelegate[k] = value;
}
public void set(Double value, int i, int j, int k, int l) {
Object[] subdelegate = getArray(delegate, i, j, k);
subdelegate[l] = value;
}
public void set(Double value, int i, int j, int k, int l, int... rest) {
Object[] subdelegate = getArray(delegate, i, j, k, rest);
subdelegate[rest[rest.length - 1]] = value;
}
}
static class Array2 {
private final Double[] delegate;
private final int[] pows;
public Array2(int... is) {
pows = new int[is.length];
int size = 1;
/*
* for (int k = 0; k < is.length; ++k) { pows[k] = size; size *=
* is[k]; }
*/
for (int k = is.length - 1; k >= 0; --k) {
pows[k] = size;
size *= is[k];
}
delegate = new Double[size];
}
private int getPosition(int i) {
int pos = i * pows[0];
return pos;
}
private int getPosition(int i, int j) {
int pos = i * pows[0];
pos += j * pows[1];
return pos;
}
private int getPosition(int i, int j, int k) {
int pos = i * pows[0];
pos += j * pows[1];
pos += k * pows[2];
return pos;
}
private int getPosition(int i, int j, int k, int l) {
int pos = i * pows[0];
pos += j * pows[1];
pos += k * pows[2];
pos += l * pows[3];
return pos;
}
private int getPosition(int i, int j, int k, int l, int... rest) {
int pos = i * pows[0];
pos += j * pows[1];
pos += k * pows[2];
pos += l * pows[3];
for (int ii = 0; ii < rest.length; ++ii) {
pos += rest[ii] * pows[ii + 4];
}
return pos;
}
public Double get(int i) {
return delegate[getPosition(i)];
}
public Double get(int i, int j) {
return delegate[getPosition(i, j)];
}
public Double get(int i, int j, int k) {
return delegate[getPosition(i, j, k)];
}
public Double get(int i, int j, int k, int l) {
return delegate[getPosition(i, j, k, l)];
}
public Double get(int i, int j, int k, int l, int... rest) {
return delegate[getPosition(i, j, k, l, rest)];
}
public void set(Double value, int i) {
delegate[getPosition(i)] = value;
}
public void set(Double value, int i, int j) {
delegate[getPosition(i, j)] = value;
}
public void set(Double value, int i, int j, int k) {
delegate[getPosition(i, j, k)] = value;
}
public void set(Double value, int i, int j, int k, int l) {
delegate[getPosition(i, j, k, l)] = value;
}
public void set(Double value, int i, int j, int k, int l, int... rest) {
delegate[getPosition(i, j, k, l, rest)] = value;
}
}
static private final int numattempts = 3;
static private final int[] dims = { 200, 100, 20, 150 };
static private double[] data;
static private Array1 array1;
static private Array2 array2;
static private Double[][][][] array3;
public static void writing1() {
String title = "Writing array1 (nested Object[])";
long start, end;
System.out.println(title);
for (int attempt = 0; attempt < numattempts; ++attempt) {
System.out.println("Attempt: " + attempt);
start = System.nanoTime();
int ii = 0;
for (int i = 0; i < dims[0]; ++i) {
for (int j = 0; j < dims[1]; ++j) {
for (int k = 0; k < dims[2]; ++k) {
for (int l = 0; l < dims[3]; ++l) {
array1.set(data[ii], i, j, k, l);
ii++;
}
}
}
}
end = System.nanoTime();
System.out.println("Attempt " + attempt + " done. " + ii + " elements in " + (double) (end - start) / 1000000000 + " seconds");
}
}
public static void writing2() {
String title = "Writing array2 (mapped plain Double[])";
long start, end;
System.out.println(title);
for (int attempt = 0; attempt < numattempts; ++attempt) {
System.out.println("Attempt: " + attempt);
start = System.nanoTime();
int ii = 0;
for (int i = 0; i < dims[0]; ++i) {
for (int j = 0; j < dims[1]; ++j) {
for (int k = 0; k < dims[2]; ++k) {
for (int l = 0; l < dims[3]; ++l) {
array2.set(data[ii], i, j, k, l);
ii++;
}
}
}
}
end = System.nanoTime();
System.out.println("Attempt " + attempt + " done. " + ii + " elements in " + (double) (end - start) / 1000000000 + " seconds");
}
}
public static void writing3() {
String title = "Writing array3 (conventional)";
long start, end;
System.out.println(title);
for (int attempt = 0; attempt < numattempts; ++attempt) {
System.out.println("Attempt: " + attempt);
start = System.nanoTime();
int ii = 0;
for (int i = 0; i < dims[0]; ++i) {
for (int j = 0; j < dims[1]; ++j) {
for (int k = 0; k < dims[2]; ++k) {
for (int l = 0; l < dims[3]; ++l) {
array3[i][j][k][l] = data[ii];
ii++;
}
}
}
}
end = System.nanoTime();
System.out.println("Attempt " + attempt + " done. " + ii + " elements in " + (double) (end - start) / 1000000000 + " seconds");
}
}
public static void reading1() {
String title = "Reading array1 (nested Object[])";
long start, end;
System.out.println(title);
for (int attempt = 0; attempt < numattempts; ++attempt) {
System.out.println("Attempt: " + attempt);
start = System.nanoTime();
int ii = 0;
for (int i = 0; i < dims[0]; ++i) {
for (int j = 0; j < dims[1]; ++j) {
for (int k = 0; k < dims[2]; ++k) {
for (int l = 0; l < dims[3]; ++l) {
assert (data[ii] == array1.get(i, j, k, l));
ii++;
}
}
}
}
end = System.nanoTime();
System.out.println("Attempt " + attempt + " done. " + ii + " elements in " + (double) (end - start) / 1000000000 + " seconds");
}
}
public static void reading2() {
String title = "Reading array2 (mapped plain Double[])";
long start, end;
System.out.println(title);
for (int attempt = 0; attempt < numattempts; ++attempt) {
System.out.println("Attempt: " + attempt);
start = System.nanoTime();
int ii = 0;
for (int i = 0; i < dims[0]; ++i) {
for (int j = 0; j < dims[1]; ++j) {
for (int k = 0; k < dims[2]; ++k) {
for (int l = 0; l < dims[3]; ++l) {
assert (data[ii] == array2.get(i, j, k, l));
ii++;
}
}
}
}
end = System.nanoTime();
System.out.println("Attempt " + attempt + " done. " + ii + " elements in " + (double) (end - start) / 1000000000 + " seconds");
}
}
public static void reading3() {
String title = "Reading array3 (conventional)";
long start, end;
System.out.println(title);
for (int attempt = 0; attempt < numattempts; ++attempt) {
System.out.println("Attempt: " + attempt);
start = System.nanoTime();
int ii = 0;
for (int i = 0; i < dims[0]; ++i) {
for (int j = 0; j < dims[1]; ++j) {
for (int k = 0; k < dims[2]; ++k) {
for (int l = 0; l < dims[3]; ++l) {
assert (array3[i][j][k][l] == data[ii]);
ii++;
}
}
}
}
end = System.nanoTime();
System.out.println("Attempt " + attempt + " done. " + ii + " elements in " + (double) (end - start) / 1000000000 + " seconds");
}
}
static void doWork() {
int ii;
long start, end;
start = System.nanoTime();
System.out.println("Allocating all arrays...");
int size = 1;
for (int i = 0; i < dims.length; ++i) {
size *= dims[i];
}
data = new double[size];
for (int i = 0; i < data.length; ++i) {
data[i] = Math.random();
}
array1 = new Array1(dims);
array2 = new Array2(dims);
array3 = new Double[dims[0]][dims[1]][dims[2]][dims[3]];
System.out.println("Done.");
writing1();
writing2();
writing3();
reading1();
reading2();
reading3();
end = System.nanoTime();
// elapsed = end - start;
System.out.println("Total application time is " + (double) (end - start) / 1000000000 + " seconds");
}
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
System.err.println("run" + i);
System.gc();
doWork();
}
}
}
@simbo1905
Copy link
Author

There are GCs during the final run but trying different combinations I would say that Array2 is as fast as the native version when you don't have a lot of GC. The final run (run2) shows a lot of GC for me:

[Full GC (System) 111.760: [Tenuredrun2
: 6616571K->5407292K(9012156K), 17.7240530 secs] 10101650K->5407292K(13067708K), [Perm : 2744K->2744K(21248K)], 17.7240860 secs] [Times: user=17.21 sys=0.39, real=17.73 secs]
Allocating all arrays...
Done.
Writing array1 (nested Object[])
Attempt: 0
Attempt 0 done. 60000000 elements in 0.476992 seconds
Attempt: 1
132.148: [GC 132.148: [DefNew: 3604992K->450560K(4055552K), 3.2740220 secs] 9012284K->8001832K(13067708K), 3.2740450 secs] [Times: user=3.05 sys=0.22, real=3.27 secs]
Attempt 1 done. 60000000 elements in 3.819678 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.444261 seconds
Writing array2 (mapped plain Double[])
Attempt: 0
Attempt 0 done. 60000000 elements in 0.413577 seconds
Attempt: 1
136.543: [GC 136.543: [DefNew: 4055552K->450559K(4055552K), 8.4108210 secs]144.954: [Tenured: 10363771K->4001042K(10363836K), 25.0703660 secs] 11606824K->4001042K(14419388K), [Perm : 2745K->2745K(21248K)], 33.6688330 secs] [Times: user=21.18 sys=7.79, real=33.66 secs]
Attempt 1 done. 60000000 elements in 35.051286 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 1.557291 seconds
Writing array3 (conventional)
Attempt: 0
173.600: [GC 173.600: [DefNew: 3604992K->450559K(4055552K), 5.7310300 secs] 7606034K->6596466K(13067708K), 5.7310520 secs] [Times: user=5.11 sys=0.62, real=5.73 secs]
Attempt 0 done. 60000000 elements in 6.373463 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 0.391081 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 0.422935 seconds
Reading array1 (nested Object[])
Attempt: 0
Attempt 0 done. 60000000 elements in 5.5E-5 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 5.5E-5 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 5.5E-5 seconds
Reading array2 (mapped plain Double[])
Attempt: 0
Attempt 0 done. 60000000 elements in 5.5E-5 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 5.5E-5 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 5.6E-5 seconds
Reading array3 (conventional)
Attempt: 0
Attempt 0 done. 60000000 elements in 5.5E-5 seconds
Attempt: 1
Attempt 1 done. 60000000 elements in 5.5E-5 seconds
Attempt: 2
Attempt 2 done. 60000000 elements in 5.6E-5 seconds

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment