From 410425c833f0652b174af2741ab00963974c95fe Mon Sep 17 00:00:00 2001 From: Van Phu DO Date: Sun, 21 Jan 2024 21:25:18 +0900 Subject: [PATCH] reorganize code, little bit faster (#509) --- prepare_abeobk.sh | 2 +- .../onebrc/CalculateAverage_abeobk.java | 51 ++++++++++--------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/prepare_abeobk.sh b/prepare_abeobk.sh index bf2b7b5..fac7b87 100755 --- a/prepare_abeobk.sh +++ b/prepare_abeobk.sh @@ -20,6 +20,6 @@ sdk use java 21.0.1-graal 1>&2 # ./mvnw clean verify removes target/ and will re-trigger native image creation. if [ ! -f target/CalculateAverage_abeobk_image ]; then - NATIVE_IMAGE_OPTS="--gc=epsilon -O3 -march=native --enable-preview" + NATIVE_IMAGE_OPTS="--gc=epsilon -O3 -march=native -R:MaxHeapSize=128m --enable-preview --initialize-at-build-time=dev.morling.onebrc.CalculateAverage_abeobk" native-image $NATIVE_IMAGE_OPTS -cp target/average-1.0.0-SNAPSHOT.jar -o target/CalculateAverage_abeobk_image dev.morling.onebrc.CalculateAverage_abeobk fi diff --git a/src/main/java/dev/morling/onebrc/CalculateAverage_abeobk.java b/src/main/java/dev/morling/onebrc/CalculateAverage_abeobk.java index cdc2c1e..48d9da6 100644 --- a/src/main/java/dev/morling/onebrc/CalculateAverage_abeobk.java +++ b/src/main/java/dev/morling/onebrc/CalculateAverage_abeobk.java @@ -47,6 +47,10 @@ public class CalculateAverage_abeobk { 0xffffffffffffffL, 0xffffffffffffffffL, }; + private static final void debug(String s, Object... args) { + System.out.println(String.format(s, args)); + } + private static Unsafe initUnsafe() { try { Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); @@ -110,7 +114,7 @@ public class CalculateAverage_abeobk { } boolean contentEquals(long other_addr, long other_tail) { - if (tail != other_tail) // compare tail & length at the same time + if (tail != other_tail) return false; // this is faster than comparision if key is short long xsum = 0; @@ -182,13 +186,15 @@ public class CalculateAverage_abeobk { // about 50% chance key < 8 chars if (semipos_code != 0) { int semi_pos = Long.numberOfTrailingZeros(semipos_code) >>> 3; - addr += semi_pos; + addr += semi_pos + 1; + long num_word = UNSAFE.getLong(addr); + int dot_pos = Long.numberOfTrailingZeros(~num_word & 0x10101000); + addr += (dot_pos >>> 3) + 3; + tail = (word0 & HASH_MASKS[semi_pos]); bucket = xxh32(tail) & BUCKET_MASK; - long num_word = UNSAFE.getLong(++addr); - int dot_pos = Long.numberOfTrailingZeros(~num_word & 0x10101000); val = parseNum(num_word, dot_pos); - addr += (dot_pos >>> 3) + 3; + while (true) { var node = map[bucket]; if (node == null) { @@ -214,14 +220,15 @@ public class CalculateAverage_abeobk { if (semipos_code != 0) { int semi_pos = Long.numberOfTrailingZeros(semipos_code) >>> 3; addr += semi_pos; + int keylen = (int) (addr - row_addr); + long num_word = UNSAFE.getLong(addr + 1); + int dot_pos = Long.numberOfTrailingZeros(~num_word & 0x10101000); + addr += (dot_pos >>> 3) + 4; + tail = (word & HASH_MASKS[semi_pos]); hash ^= tail; bucket = xxh32(hash) & BUCKET_MASK; - int keylen = (int) (addr - row_addr); - long num_word = UNSAFE.getLong(++addr); - int dot_pos = Long.numberOfTrailingZeros(~num_word & 0x10101000); val = parseNum(num_word, dot_pos); - addr += (dot_pos >>> 3) + 3; while (true) { var node = map[bucket]; @@ -249,16 +256,15 @@ public class CalculateAverage_abeobk { int semi_pos = Long.numberOfTrailingZeros(semipos_code) >>> 3; addr += semi_pos; + int keylen = (int) (addr - row_addr); + long num_word = UNSAFE.getLong(addr + 1); + int dot_pos = Long.numberOfTrailingZeros(~num_word & 0x10101000); + addr += (dot_pos >>> 3) + 4; + tail = (word & HASH_MASKS[semi_pos]); hash ^= tail; bucket = xxh32(hash) & BUCKET_MASK; - int keylen = (int) (addr - row_addr); - - long num_word = UNSAFE.getLong(++addr); - - int dot_pos = Long.numberOfTrailingZeros(~num_word & 0x10101000); val = parseNum(num_word, dot_pos); - addr += (dot_pos >>> 3) + 3; while (true) { var node = map[bucket]; @@ -307,12 +313,6 @@ public class CalculateAverage_abeobk { for (var thread : threads) thread.join(); - if (SHOW_ANALYSIS) { - for (int i = 0; i < cpu_cnt; i++) { - System.out.println("thread-" + i + " collision = " + cls[i]); - } - } - // collect results TreeMap ms = new TreeMap<>(); for (var map : maps) { @@ -330,13 +330,16 @@ public class CalculateAverage_abeobk { } if (SHOW_ANALYSIS) { - System.out.println("total=" + Arrays.stream(lenhist).sum()); - System.out.println("length_histogram = " + debug("Collision stat: "); + for (int i = 0; i < cpu_cnt; i++) { + debug("thread-" + i + " collision = " + cls[i]); + } + debug("Total = " + Arrays.stream(lenhist).sum()); + debug("Length_histogram = " + Arrays.toString(Arrays.stream(lenhist).map(x -> (int) (x * 1.0e-7)).toArray())); } else System.out.println(ms); } } - } \ No newline at end of file