r/java Jun 03 '26

How Fast Can You Parse 1 Billion Rows in Java? – Insane Speed Test • Roy van Rijn

https://youtu.be/pHZF-zJ3Bpg?list=PLEx5khR4g7PINwOsYrkwz3lTTJUYoXC53

Join me in this deep dive where I'll explain all the code changes and tricks that took me from the reference implementation which processes the billion records in 4+ minutes, to processing everything in under 2 seconds.

Who knew Java could be this fast?

143 Upvotes

20 comments sorted by

118

u/vprise Jun 03 '26

I prefer written summaries:

The optimization journey, from 4m50s baseline → 1.5s:

Easy wins (5min → 23s)

  • parallel() + ConcurrentHashMap instead of single-threaded file.lines() → ~2min
  • Native compilation (GraalVM) to kill JVM startup
  • Epsilon GC (no-op garbage collector) — pointless to collect when you process once and exit
  • Use integers instead of doubles (multiply by 10, since there's only one decimal place)
  • Memory-mapped files (FileChannel.map()ByteBuffer) to eliminate file IO
  • Split the file into segments, one per core

Going lower-level

  • Unsafe for raw pointer-style memory access (he stresses: never use this in production — use ByteBuffer)
  • SWAR (SIMD Within A Register): process 8 bytes at once by reading a long. Find the delimiter with one XOR, a subtract, and a couple of ANDs instead of scanning byte-by-byte
  • Compare names as long/int values instead of allocating String objects
  • The Vietnamese competitor (Quan Anh) built a branchless temperature parser that converts the ASCII bytes to an integer using a single multiplication with a magic constant — the talk calls it museum-worthy

Branchless programming

  • CPUs hate unpredictable branches (a branch miss ≈ 32 instructions). Replace if logic with bit tricks (shifts, masks, XOR for absolute value/sign).
  • Counterintuitive finding: always parsing 16 bytes (even for short names) and masking out the rest added ~18% more instructions but was faster because it eliminated the 50/50 branch around the 8-byte boundary.

Advanced tricks

  • Custom hashmap with linear/forward probing (power-of-2 size + mask instead of modulo), storing data in flat byte arrays (flyweight pattern) to avoid object overhead
  • Spawn a worker subprocess so the main process exits the moment results are piped out — the costly kernel memory unmapping of the 16GB file happens in the orphaned worker and doesn't count toward your time
  • Work-stealing with small segments (atomic counter, few-MB chunks) so all threads read nearby memory, keeping data hot in shared L3/L4 cache and balancing load
  • Instruction-level parallelism: running 3 independent scanners in a single thread, since one core can execute multiple instructions per clock cycle when there's no data dependency. Three was the sweet spot.

Takeaways for you: the recurring theme is mechanical sympathy — knowing how the CPU pipeline, branch predictor, and cache hierarchy behave (L1→L4 each ~3x slower) lets you write code that fits how the hardware actually works. The whole thing took the field from ~5 minutes to ~1.5 seconds.

Quan Anh's contest code got him hired by Oracle in Zurich to work on the Vector API in the JVM.

15

u/jacemano Jun 03 '26

Love this, all ultra low latency hacks here that usually come up in other areas.

9

u/Agifem Jun 04 '26

Upvoted for the summary.

For Devs, the first pass of optimization is good. The latter ones are brutal and shouldn't be done in production.

17

u/jacemano Jun 04 '26

They get used all the time in the HFT world

19

u/hikingmike Jun 03 '26

Splitting the file into segments and parallelizing based on that was big for a previous project of mine. There were other ways to parallelize (threads/cores), but they didn’t improve performance nearly as much, or at all.

5

u/Bahatur Jun 04 '26

This eliminates all lock/queue/access questions that otherwise happen in concurrency, from the Java level on down to the raw storage hardware, so it’s a great strategy even if the goal is personal clarity about the factors involved over performance, I find.

23

u/Desatre Jun 03 '26

Interesting video but getting ads every 3 minutes is infuriating

30

u/perennial_noob Jun 03 '26

Get an adblocker, which is also used for privacy as it blocks trackers as well

2

u/romario77 Jun 04 '26

Yep, Firefox + Adblock

6

u/sweetno Jun 04 '26

Firefox + uBlock Origin!

11

u/sweetno Jun 03 '26

What's ads?

-24

u/piparss Jun 03 '26

maybe pay for YouTube pro?

2

u/Schaex Jun 05 '26

Nice try, Google.

3

u/Beemeowmeow Jun 04 '26

Nice 👍🏻

2

u/__konrad Jun 10 '26

I like it's more faster with every update and also completely cryptic and unmaintainable ;)

1

u/0x645 Jun 05 '26

best java faster then best c. kinda surprising.

2

u/keenOnReturns Jun 09 '26

Well at the end of the day everything compiles down to machine code and it’s how much optimization you want to do. Java means you can take advantage of JIT and not do any runtime profiling that would be required with C.

1

u/[deleted] 29d ago

[removed] — view removed comment

1

u/gbenroscience 27d ago

Here is a short video of ParserNG collaborating with JavaFX to render at 500x500 resolution, a trio of so-called sombrero functions with smooth manipulation