🌐 AI搜索 & 代理 主页
Skip to content

Conversation

@He-Pin
Copy link
Contributor

@He-Pin He-Pin commented Sep 22, 2025

Motivation:
I wanted to use ArrayBuffer, but found it does not override the foreach method.

refs: apache/pekko#2262

I got the number with numbers:

jmh:run -i 10 -wi 5 -f2 -t1 scala.collection.mutable.ArrayBufferBenchmark

old --

[info] Benchmark                     (size)  Mode  Cnt     Score    Error  Units
[info] ArrayBufferBenchmark.foreach   10000  avgt   10  6198.500 ± 68.184  ns/op

--- array

[info] Benchmark                     (size)  Mode  Cnt     Score    Error  Units
[info] ArrayBufferBenchmark.foreach   10000  avgt   10  3293.280 ± 45.680  ns/op

for 10000 elements only

@He-Pin He-Pin requested a review from a team as a code owner September 22, 2025 17:05
@scala-jenkins scala-jenkins added this to the 2.13.18 milestone Sep 22, 2025
@SethTisue SethTisue added the library:collections PRs involving changes to the standard collection library label Sep 22, 2025
@som-snytt
Copy link
Contributor

IndexedSeqOps overrides iterator to provide a fast indexed iterator (presumably; I didn't test anything or research it).

Obviously a tight loop with array indexing must be faster, but how much faster (IRL) and at what cost in code?

@He-Pin
Copy link
Contributor Author

He-Pin commented Sep 23, 2025

I agree, but I want it as fast as Java's ArrayList

@Ichoran
Copy link
Contributor

Ichoran commented Sep 23, 2025

Do you know that it is slower?

@He-Pin
Copy link
Contributor Author

He-Pin commented Sep 23, 2025

@Ichoran I don't think Java's ArrayList is slower; Java's ArrayList overrides the forEach method

@lrytz
Copy link
Member

lrytz commented Sep 23, 2025

I think the question is: did you test that your change makes foreach faster than the current version based on iterator?

There's an existing benchmark class: https://github.com/scala/scala/blob/2.13.x/test/benchmarks/src/main/scala/scala/collection/mutable/ArrayBufferBenchmark.scala. You could add some benchmarks to compare before/after, and also compare to Java's ArrayList.

@He-Pin
Copy link
Contributor Author

He-Pin commented Sep 23, 2025

I got the number with numbers:

jmh:run -i 10 -wi 5 -f2 -t1 scala.collection.mutable.ArrayBufferBenchmark

old --

[info] Benchmark                     (size)  Mode  Cnt     Score    Error  Units
[info] ArrayBufferBenchmark.foreach   10000  avgt   10  6198.500 ± 68.184  ns/op

--- array

[info] Benchmark                     (size)  Mode  Cnt     Score    Error  Units
[info] ArrayBufferBenchmark.foreach   10000  avgt   10  3293.280 ± 45.680  ns/op

for 10000 elements only

@Ichoran
Copy link
Contributor

Ichoran commented Sep 23, 2025

Okay, that looks pretty compelling! I guess the JIT compiler is not doing a good job eliding the extra work in this case.

@SethTisue SethTisue added the performance the need for speed. usually compiler performance, sometimes runtime performance. label Sep 23, 2025
@SethTisue SethTisue changed the title chore: override some methods of ArrayBuffer to work on array Performance: override some methods of ArrayBuffer to operate directly on internal array Sep 23, 2025
@lrytz
Copy link
Member

lrytz commented Oct 27, 2025

With this numbers, adding some overrides looks worthwhile indeed.

Questions:

  • how can we come up with a selection of methods to override that is not arbitrary?
  • there are more array-based collections, the same overrides should be applied to all of them: mutable.ArraySeq, immutable.ArraySeq, mutable.ArrayDeque (-> Queue / Stack). They are all classes (not traits), so adding overrides should be possible in a binary compatible manner.
  • how can we share code (implementations, overriding signatures)?

Probably it's worth looking at ArrayOps. Can we re-use these implementations?

@He-Pin
Copy link
Contributor Author

He-Pin commented Oct 27, 2025

I totally missed other types, because I wanted to use the ArrayBuffer as an ArrayDeque.

Maybe we should add these optimizations in StrictOptimizedSeqOps/StrictOptimizedIterableOps?

@lrytz
Copy link
Member

lrytz commented Oct 27, 2025

I don't think the StrictOptimized traits are the right place, for example ArraySeq.foreach is not overridden at all, it's inherited from IterableOnceOps.

@lrytz lrytz marked this pull request as draft November 3, 2025 09:24
@lrytz lrytz modified the milestones: 2.13.18, 2.13.19 Nov 3, 2025
@He-Pin He-Pin force-pushed the bufferArray branch 2 times, most recently from f1d114d to d8cf863 Compare November 3, 2025 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

library:collections PRs involving changes to the standard collection library performance the need for speed. usually compiler performance, sometimes runtime performance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants