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

Scala performance fix: Use Double instead of Float to avoid autoboxing #24

Merged
merged 1 commit into from
Apr 15, 2020

Conversation

witi83
Copy link

@witi83 witi83 commented Apr 15, 2020

Your code gets twice as fast when you use Double instead of Float. I just replaced all occurrences via search+replace. In my case:

  • Before: Rendering took: 2517.6652006ms (average over 5 repetitions)
  • After: Rendering took: 1254.6068284ms (average over 5 repetitions)

Among other things, autoboxing occurs when using tuples with Float. Only Doubles are spezialized: https://github.com/scala/scala/blob/v2.13.1/src/library/scala/Tuple2.scala#L24

Besides, your precision rises from 32 bit (Float) to 64 bit (Double), which results in a nicer output image.

Signed-off-by: Witold Czaplewski <[email protected]>
@ForNeVeR
Copy link

Fun fact is that we were experiencing 25% speed up in F# when switching from float64 to float32.

All of this is getting really messy now.

@athas
Copy link
Owner

athas commented Apr 15, 2020

Thanks! The ways of parallel functional programming are mysterious indeed.

@athas athas merged commit 3a51d14 into athas:master Apr 15, 2020
athas added a commit that referenced this pull request Apr 15, 2020
@olafurpg
Copy link
Contributor

It doesn't seem to make a difference whether you use Float or Double when running the benchmarks on GraalVM 20.0.0, both are similarly optimized

# With Float (current master after reverting this PR)
[info] Benchmark        (scene)  Mode  Cnt    Score     Error  Units
[info] Bench.construct   rgbbox  avgt    3    0.200 ±   0.067  ms/op
[info] Bench.construct    irreg  avgt    3    5.558 ±   2.903  ms/op
[info] Bench.render      rgbbox  avgt    3  766.837 ± 171.120  ms/op
[info] Bench.render       irreg  avgt    3  268.327 ±  59.585  ms/op

# With Double (current master, includes this PR)
[info] Benchmark        (scene)  Mode  Cnt    Score     Error  Units
[info] Bench.construct   rgbbox  avgt    3    0.211 ±   0.074  ms/op
[info] Bench.construct    irreg  avgt    3    5.878 ±   5.600  ms/op
[info] Bench.render      rgbbox  avgt    3  805.039 ± 152.805  ms/op
[info] Bench.render       irreg  avgt    3  278.762 ± 156.538  ms/op

@witi83
Copy link
Author

witi83 commented Apr 15, 2020

@olafurpg I'm not familiar with GraalVM and how it handles Boxing.

But using the default JVM, the question here is not Double or Float, the problem lies in Tuple2+Float. Just take a look at the implementation: https://github.com/scala/scala/blob/v2.13.1/src/library/scala/Tuple2.scala#L24 Since Float is not defined, its gets a massive performance penalty due to autoboxing. More information why Float is not defined: https://scalac.io/specialized-generics-object-instantiation/

But yeah, replacing Float with Double is just a quick fix. Rather than this you should refactor the code accordingly and avoid using Tuple+Float

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.

4 participants