mdedetrich / scalajson

ScalaJSON - JSON for Scala, currently contains minimal AST
BSD 3-Clause "New" or "Revised" License
55 stars 10 forks source link

Added JNumber conversions #38

Closed mdedetrich closed 6 years ago

mdedetrich commented 7 years ago

This is an implementation which adds various conversions from JNumber to other number types (see https://github.com/mdedetrich/scalajson/issues/37). Unlike the previous implementation, these conversions

To make the various number converter calls as performant as possible, when you construct a JNumber we store a bitFlag (called constructedFlag) which tracks how a JNumber is constructed. This means that if you construct a JNumber as a double with its argument (i.e. JNumber(3446437343d)), we first do a check against this bitflag (which is a single if statement) and immediately return a Some(value.toDouble) (since we know its a double), otherwise we do a more expensive check. This also means that the JNumber has an extra int per instance of JNumber in terms of memory (so we are trading a very small amount of extra memory for a more performant number conversion in typical use cases).

The checks were inspired from argonaut (i.e. https://github.com/argonaut-io/argonaut/blob/master/argonaut/shared/src/main/scala/argonaut/JsonNumber.scala) afaik, these are known to be correct

One note, due to how ast.unsafe.JNumber was constructed (the String constructer by default is public), we now added the a second parameter to the constructor list which is not hidden (i.e. its final case class JNumber(value: String, constructedFlag: Int = 0)) which means the unapply method has been changed. Although this change is breaking, it means the unsafe AST does give you control over specifying the constructedFlag.

To be done

Here is the current results for the benchmarks

> benchmarkJVM/testOnly scalajson.ast.JNumberConversionBenchmark
[info] ::Benchmark intBitFlagCheckSuccess::
[info] cores: 8
[info] hostname: Matthews-MacBook-Pro.local
[info] name: Java HotSpot(TM) 64-Bit Server VM
[info] osArch: x86_64
[info] osName: Mac OS X
[info] vendor: Oracle Corporation
[info] version: 25.111-b14
[info] Parameters(seed -> 300000): 0.004583
[info] Parameters(seed -> 600000): 0.004508
[info] Parameters(seed -> 900000): 0.00365
[info] Parameters(seed -> 1200000): 0.003651
[info] Parameters(seed -> 1500000): 0.003779
[info]
[info] ::Benchmark intManualCheckSuccess::
[info] cores: 8
[info] hostname: Matthews-MacBook-Pro.local
[info] name: Java HotSpot(TM) 64-Bit Server VM
[info] osArch: x86_64
[info] osName: Mac OS X
[info] vendor: Oracle Corporation
[info] version: 25.111-b14
[info] Parameters(seed -> 300000): 0.008185
[info] Parameters(seed -> 600000): 0.007592
[info] Parameters(seed -> 900000): 0.007627
[info] Parameters(seed -> 1200000): 0.007783
[info] Parameters(seed -> 1500000): 0.007503
[info]
[info] ::Benchmark floatBitFlagCheckSuccess::
[info] cores: 8
[info] hostname: Matthews-MacBook-Pro.local
[info] name: Java HotSpot(TM) 64-Bit Server VM
[info] osArch: x86_64
[info] osName: Mac OS X
[info] vendor: Oracle Corporation
[info] version: 25.111-b14
[info] Parameters(seed -> 300000): 0.004514
[info] Parameters(seed -> 600000): 0.004442
[info] Parameters(seed -> 900000): 0.00447
[info] Parameters(seed -> 1200000): 0.010328
[info] Parameters(seed -> 1500000): 0.010266
[info] Parameters(seed -> 300000): 0.004446
[info] Parameters(seed -> 600000): 0.004409
[info] Parameters(seed -> 900000): 0.004563
[info] Parameters(seed -> 1200000): 0.010455
[info] Parameters(seed -> 1500000): 0.010432
[info] Parameters(seed -> 300000): 0.004532
[info] Parameters(seed -> 600000): 0.004559
[info] Parameters(seed -> 900000): 0.004381
[info] Parameters(seed -> 1200000): 0.010438
[info] Parameters(seed -> 1500000): 0.01039
[info] Parameters(seed -> 300000): 0.004513
[info] Parameters(seed -> 600000): 0.004333
[info] Parameters(seed -> 900000): 0.004222
[info] Parameters(seed -> 1200000): 0.010413
[info] Parameters(seed -> 1500000): 0.010087
[info] Parameters(seed -> 300000): 0.004332
[info] Parameters(seed -> 600000): 0.004259
[info] Parameters(seed -> 900000): 0.004153
[info] Parameters(seed -> 1200000): 0.010197
[info] Parameters(seed -> 1500000): 0.010366
[info]
[info] ::Benchmark floatManualCheckSuccess::
[info] cores: 8
[info] hostname: Matthews-MacBook-Pro.local
[info] name: Java HotSpot(TM) 64-Bit Server VM
[info] osArch: x86_64
[info] osName: Mac OS X
[info] vendor: Oracle Corporation
[info] version: 25.111-b14
[info] Parameters(seed -> 300000): 0.016463
[info] Parameters(seed -> 600000): 0.016133
[info] Parameters(seed -> 900000): 0.015968
[info] Parameters(seed -> 1200000): 0.02228
[info] Parameters(seed -> 1500000): 0.022384
[info] Parameters(seed -> 300000): 0.016113
[info] Parameters(seed -> 600000): 0.016185
[info] Parameters(seed -> 900000): 0.0167
[info] Parameters(seed -> 1200000): 0.023496
[info] Parameters(seed -> 1500000): 0.022714
[info] Parameters(seed -> 300000): 0.016185
[info] Parameters(seed -> 600000): 0.016222
[info] Parameters(seed -> 900000): 0.016077
[info] Parameters(seed -> 1200000): 0.022478
[info] Parameters(seed -> 1500000): 0.022686
[info] Parameters(seed -> 300000): 0.016302
[info] Parameters(seed -> 600000): 0.016113
[info] Parameters(seed -> 900000): 0.015989
[info] Parameters(seed -> 1200000): 0.022411
[info] Parameters(seed -> 1500000): 0.022288
[info] Parameters(seed -> 300000): 0.016191
[info] Parameters(seed -> 600000): 0.016106
[info] Parameters(seed -> 900000): 0.015932
[info] Parameters(seed -> 1200000): 0.022691
[info] Parameters(seed -> 1500000): 0.022319
[info]
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0

@ktoso @travisbrown @Ichoran @eed3si9n @sirthias Thoughts?

codecov-io commented 7 years ago

Codecov Report

Merging #38 into master will decrease coverage by 9.25%. The diff coverage is 17.58%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #38      +/-   ##
==========================================
- Coverage   44.68%   35.43%   -9.26%     
==========================================
  Files           5        5              
  Lines         687      906     +219     
  Branches      133      194      +61     
==========================================
+ Hits          307      321      +14     
- Misses        380      585     +205
Impacted Files Coverage Δ
...s/src/main/scala/scalajson/ast/unsafe/JValue.scala 0% <0%> (ø) :arrow_up:
js/src/main/scala/scalajson/ast/JValue.scala 0% <0%> (ø) :arrow_up:
shared/src/main/scala/scalajson/ast/package.scala 59.91% <100%> (+2.13%) :arrow_up:
...m/src/main/scala/scalajson/ast/unsafe/JValue.scala 42.79% <22.97%> (-16.72%) :arrow_down:
jvm/src/main/scala/scalajson/ast/JValue.scala 47.36% <25.67%> (-26.03%) :arrow_down:

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update fd5637b...171f30d. Read the comment docs.