Skip to content

manually inline IntArrayList for BitOps.Writer perf#27

Closed
niklasf wants to merge 1 commit intomasterfrom
bitops-writer
Closed

manually inline IntArrayList for BitOps.Writer perf#27
niklasf wants to merge 1 commit intomasterfrom
bitops-writer

Conversation

@niklasf
Copy link
Member

@niklasf niklasf commented Nov 16, 2025

so for me, all benchmarks are now improved since 3.1.2~4, except OverallEncodingTest.testEncode (with benchmarks/jmh:run -i 4 -wi 5 -f10):

OverallEncodingTest.testEncode  avgt   40  146.289 ± 1.398  ns/op  # 3.1.2~4
OverallEncodingTest.testEncode  avgt   40  165.154 ± 4.292  ns/op  # master (e64faf92af)

it comes down the the attached diff:

OverallEncodingTest.testEncode  avgt   40  144.381 ± 1.392  ns/op  # this pr (a87e0ad6b7)

@isaacl thoughts? could be worth keeping as is, because the separate IntArrayList is a bit clearer. or maybe we should merge this? or maybe you can spot something in the diff? or maybe it's just a thing on my machine?

@isaacl
Copy link
Member

isaacl commented Nov 16, 2025

That's odd because that diff came with improved perf on my machine, at the time.

@niklasf
Copy link
Member Author

niklasf commented Nov 16, 2025

maybe masked by other improvements?

Copy link
Member

@isaacl isaacl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This patch is negative on my machine.
jmh:run -wi 3 -i 3 -f2 OverallEncodingTest.testEncode

239.229 ±(99.9%) 47.073 ns/op [Average]
(min, avg, max) = (217.726, 239.229, 259.115), stdev = 16.787
CI (99.9%): [192.156, 286.302] (assumes normal distribution)
  • pr/27:
345.767 ±(99.9%) 136.290 ns/op [Average]
(min, avg, max) = (278.333, 345.767, 389.225), stdev = 48.602
CI (99.9%): [209.477, 482.057] (assumes normal distribution)

final class Writer:
private val buffer = new IntArrayList()
final class Writer(initialCapacity: Int = 10):
private var buffer = Array[Int](initialCapacity)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😱 This makes Array of length 1 ([10])

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lol, wtf. It was broken in 5db83df, fixed in b733ef4, and would be broken again with this PR.

@niklasf
Copy link
Member Author

niklasf commented Nov 19, 2025

So with that bug, it turns out we're essentially benchmarking initialCapacity 10 vs 1. And indeed I see the same improvement from just

--- a/src/main/scala/BitOps.scala
+++ b/src/main/scala/BitOps.scala
@@ -96,7 +96,7 @@ object BitOps:
       bb.array

   private final class IntArrayList:
-    private var data  = new Array[Int](10)
+    private var data  = new Array[Int](1)
     private var index = 0

     def add(elt: Int): Unit =

as from this PR.

Now it's still weird that our PCs have different tastes with regard to that value, but it makes no sense to tune this for the fixed input size in the benchmark in any case.

@niklasf niklasf closed this Nov 19, 2025
@niklasf niklasf deleted the bitops-writer branch November 19, 2025 18:58
@isaacl
Copy link
Member

isaacl commented Nov 19, 2025

Agree on not optimizing initial array length to this benchmark.

But given you see a difference from initial length, I wonder if initial size and growth factor are tuned well. These were copied from ArrayList, but there they are worried about memory usage of a long living object. OTOH, IntArrayList is always transient.

So maybe it should have larger initial capacity and/or grow faster?

@niklasf
Copy link
Member Author

niklasf commented Nov 19, 2025

Or maybe have the encoders provide a guess for the required capacity, probably slightly overestimating, so that the growth strategy would rarely be used?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants