Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specialize ByteIterator in BinaryFen #619

Closed
wants to merge 2 commits into from

Conversation

som-snytt
Copy link

Noticed in Scala community build.

The iterator tries to inline to the underlying without much success.

The latest Scala will rewrite unused imports, so that's a second commit.

As a footnote, "bare iterators" should normally extend collection.AbstractIterator to save on members.

@som-snytt
Copy link
Author

It's interesting that the import in the test of the extension just works, competing with the implicit def in predef.

@som-snytt
Copy link
Author

I don't resist scalafmt per se, but one-lining an extension makes it extend longer. The result is that I remove explicit types to make lines shorter.

image

Appeasing scalafmt

image

Maybe making the variables private would look better. I don't have a lot of experience with scalafmt.

@lenguyenthanh
Copy link
Member

lenguyenthanh commented Feb 4, 2025

Thanks @som-snytt this looks great ❤️

We have benchmark for this BinaryFen, so I'll run it to see the result

The iterator tries to inline to the underlying without much success.

Just wonder what scalac otions do you use to notice such a thing.

I don't resist scalafmt per se, but one-lining an extension makes it extend longer. The result is that I remove explicit types to make lines shorter.

I think this is a good call, I don't agree with scalafmt a lot of time, but it's good to be consistent with code style.

Maybe making the variables private would look better. I don't have a lot of experience with scalafmt.

I think we can make this class IteratorOfBye private but it shouldn't master much.

@lenguyenthanh
Copy link
Member

There is no different in the the benchmark within margin of error, maybe jit compiler takes care of the inlining things?

master:

[info] Benchmark              Mode  Cnt        Score       Error  Units
[info] BinaryFenBench.read   thrpt   45  5550976.025 ± 41616.736  ops/s
[info] BinaryFenBench.write  thrpt   45  3997816.760 ± 29362.134  ops/s
[info] Benchmark result is saved to jmh-result.json

Pr:

[info] Benchmark              Mode  Cnt        Score       Error  Units                                                                                                                                               │
[info] BinaryFenBench.read   thrpt   45  5496608.257 ± 44021.886  ops/s                                                                                                                                               │
[info] BinaryFenBench.write  thrpt   45  4014106.685 ± 14020.498  ops/s                                                                                                                                               │
[info] Benchmark result is saved to jmh-result.json

@som-snytt
Copy link
Author

Anything is possible with runtime.

I noticed because of a bug with -Wunused that made me try the project and that showed another bug
scala/scala3#22507

This was more of a learning exercise about array iterator. Normally I would not optimize without measuring.

I noticed in the discussion about future inline trait they are casual about unspecialized interfaces, so probably they lean on the JIT.

@som-snytt som-snytt marked this pull request as draft February 4, 2025 18:22
@som-snytt
Copy link
Author

som-snytt commented Feb 4, 2025

I also don't see a change in the benchmark. I'll check using AbstractIterator, which has the fixed benefit of a smaller class file (which makes it easier to examine the bytecode of next and hasNext; though all that matters is the jitted code!).

Edit: as expected, AbstractIterator can be used without affecting performance (or at least the benchmark). I'll close this PR as unnecessary ceremony.

@som-snytt som-snytt closed this Feb 4, 2025
@lenguyenthanh
Copy link
Member

hey, thanks anyway! We at least can cherry pick your removing imports commit.

I'm messing around with BinaryFen benchmark as it seems too simple (only one case) and compiler may constant folds it.

Edit: as expected, AbstractIterator can be used without affecting performance (or at least the benchmark). I'll close this PR as unnecessary ceremony.

Do you suggest to replace Iterator with AbstractIterator, as you mention in scala/scala3#22507?

@lenguyenthanh
Copy link
Member

new benchmark code #620 and still nothing significant.

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