Skip to content

Commit 0af7536

Browse files
dfa1claude
andcommitted
refactor: use fold in benchmarks, add DoubleArray#fold
Replace long[]{0}/double[]{0} accumulator trick with fold. Add DoubleBinaryOperator-based fold to DoubleArray mirroring LongArray. No throughput change (same loop, cleaner API). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent fee9e42 commit 0af7536

2 files changed

Lines changed: 21 additions & 8 deletions

File tree

core/src/main/java/io/github/dfa1/vortex/core/array/DoubleArray.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.lang.foreign.MemorySegment;
88
import java.lang.foreign.ValueLayout;
99
import java.nio.ByteOrder;
10+
import java.util.function.DoubleBinaryOperator;
1011
import java.util.function.DoubleConsumer;
1112

1213
/// Concrete [Array] for F64 primitive columns. Hoists a single `MemorySegment`,
@@ -65,4 +66,14 @@ public void forEachDouble(DoubleConsumer c) {
6566
c.accept(buf.getAtIndex(LAYOUT, i));
6667
}
6768
}
69+
70+
public double fold(double identity, DoubleBinaryOperator op) {
71+
MemorySegment buf = buffer;
72+
long n = length;
73+
double result = identity;
74+
for (long i = 0; i < n; i++) {
75+
result = op.applyAsDouble(result, buf.getAtIndex(LAYOUT, i));
76+
}
77+
return result;
78+
}
6879
}

performance/src/main/java/io/github/dfa1/vortex/performance/RustVsJavaReadBenchmark.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import dev.vortex.api.Session;
99
import dev.vortex.arrow.ArrowAllocation;
1010
import dev.vortex.jni.NativeLoader;
11+
import io.github.dfa1.vortex.core.array.DoubleArray;
12+
import io.github.dfa1.vortex.core.array.LongArray;
1113
import io.github.dfa1.vortex.encoding.CodecRegistry;
1214
import io.github.dfa1.vortex.io.VortexReader;
1315
import io.github.dfa1.vortex.scan.ScanResult;
@@ -208,32 +210,32 @@ public long jniReadSymbol() throws IOException {
208210

209211
// ── JNI file generation ───────────────────────────────────────────────────
210212

211-
/// Java read: project on "volume", sum all values via typed `forEachLong`.
213+
/// Java read: project on "volume", sum all values via fold.
212214
@Benchmark
213215
public long javaReadVolume() throws IOException {
214-
long[] sum = {0L};
216+
long sum = 0L;
215217
try (VortexReader vf = VortexReader.open(benchFile, registry)) {
216218
var iter = vf.scan(io.github.dfa1.vortex.scan.ScanOptions.columns("volume"));
217219
while (iter.hasNext()) {
218220
ScanResult r = iter.next();
219-
r.columns().get("volume").forEachLong(v -> sum[0] += v);
221+
sum += r.<LongArray>column("volume").fold(0L, Long::sum);
220222
}
221223
}
222-
return sum[0];
224+
return sum;
223225
}
224226

225-
/// Java read: project on "close" (F64, ALP-encoded), sum via typed `forEachDouble`.
227+
/// Java read: project on "close" (F64, ALP-encoded), sum via fold.
226228
@Benchmark
227229
public double javaReadClose() throws IOException {
228-
double[] sum = {0.0};
230+
double sum = 0.0;
229231
try (VortexReader vf = VortexReader.open(benchFile, registry)) {
230232
var iter = vf.scan(io.github.dfa1.vortex.scan.ScanOptions.columns("close"));
231233
while (iter.hasNext()) {
232234
ScanResult r = iter.next();
233-
r.columns().get("close").forEachDouble(v -> sum[0] += v);
235+
sum += r.<DoubleArray>column("close").fold(0.0, Double::sum);
234236
}
235237
}
236-
return sum[0];
238+
return sum;
237239
}
238240

239241
/// Java read: project on "symbol" (short UTF-8 string, varbin), sum byte lengths.

0 commit comments

Comments
 (0)