Created
November 10, 2014 17:42
-
-
Save simbo1905/7a2404b8fe9e8b2488c8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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