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

Fix construction with same type performing convert #36

Merged
merged 1 commit into from
Nov 5, 2018

Conversation

NHDaly
Copy link
Member

@NHDaly NHDaly commented Nov 2, 2018

Before this PR, constructing a new FD with the same type called convert. That happened due to this line, since FD<: Real:

(::Type{T})(x::Real) where {T <: FD} = convert(T, x)

julia> f =  FixedPointDecimals.FixedDecimal{Int8, 2}(1)
>> FixedDecimal{Int8,2}(1.00)

julia> @which typeof(f)(f)
>> (::Type{T})(x::Real) where T<:FixedDecimal in FixedPointDecimals at /Users/daly/.julia/dev/FixedPointDecimals/src/FixedPointDecimals.jl:113

This PR adds a "copy constructor" to avoid that. I'm not really sure what the idiomatic name for it would be in julia, "copy constructor" of course references the name of the same concept in C++. :)

Perhaps a separate issue is that for some reason convert is super expensive when T=Int128, which is how I stumbled across this problem. But either way, i think this PR could make sense.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.007%) to 98.824% when pulling 4634bc8 on NHDaly:copy-constructor into cc6aed3 on JuliaMath:master.

@coveralls
Copy link

coveralls commented Nov 2, 2018

Coverage Status

Coverage increased (+0.007%) to 98.824% when pulling 1ad557e on NHDaly:copy-constructor into cc6aed3 on JuliaMath:master.

@codecov-io
Copy link

codecov-io commented Nov 2, 2018

Codecov Report

Merging #36 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #36      +/-   ##
==========================================
+ Coverage   98.81%   98.82%   +<.01%     
==========================================
  Files           1        1              
  Lines         169      170       +1     
==========================================
+ Hits          167      168       +1     
  Misses          2        2
Impacted Files Coverage Δ
src/FixedPointDecimals.jl 98.82% <100%> (ø) ⬆️

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 cc6aed3...4634bc8. Read the comment docs.

@omus
Copy link
Contributor

omus commented Nov 2, 2018

Can you post some performance benchmarks?

…is the same

Before this change:
```
  julia> x = f = FixedDecimal{Int128,2}(3.25)
  >> FixedDecimal{Int128,2}(3.25)

  julia> @Btime x = FixedDecimal{Int128, 2}($f)
    7.272 μs (159 allocations: 2.73 KiB)
  >> FixedDecimal{Int128,2}(3.25)
```

After this change:
```
  julia> x = f = FixedDecimal{Int128,2}(3.25)
  >> FixedDecimal{Int128,2}(3.25)

  julia> @Btime x = FixedDecimal{Int128, 2}($f)
    1.508 ns (0 allocations: 0 bytes)
  >> FixedDecimal{Int128,2}(3.25)
```
@NHDaly
Copy link
Member Author

NHDaly commented Nov 5, 2018

Can you post some performance benchmarks?

Yes, definitely!

Sorry, i had this tiny "benchmark" in the commit text, but didn't post it in the PR:

Before this change:
```
  julia> f = FixedDecimal{Int128,2}(3.25)
  >> FixedDecimal{Int128,2}(3.25)

  julia> @btime x = FixedDecimal{Int128, 2}($f)
    7.272 μs (159 allocations: 2.73 KiB)
  >> FixedDecimal{Int128,2}(3.25)
```

After this change:
```
  julia> f = FixedDecimal{Int128,2}(3.25)
  >> FixedDecimal{Int128,2}(3.25)

  julia> @btime x = FixedDecimal{Int128, 2}($f)
    1.508 ns (0 allocations: 0 bytes)
  >> FixedDecimal{Int128,2}(3.25)
```

But I'll also post up a better benchmark in a second.

@NHDaly
Copy link
Member Author

NHDaly commented Nov 5, 2018

Okay, so here's the benchmarks that originally led me here.

Here's the benchmark in a gist:
https://gist.github.com/NHDaly/a8fae0d1d65ab1066c585c27e54146fa

And the results in a google spreadsheet:
https://docs.google.com/spreadsheets/d/1Lc3ughgwwK25cpwbnuLRxw19EtaMxdCsMmtnspT_4H8/edit?usp=sharing

For some reason, even just element-wise copying an array of FixedDecimal{Int128, 2} into another array, allocates like crazy. (14,000,000 allocations / 1,000,000 elements).

I was trying to find the source of that allocation, which led me to this change. It doesn't actually address the fact that Int128s are allocating when copied, when the other sizes don't, but it does eliminate unnecessary work, by preventing a convert call when the types are identical.

Separately, though, it would be really nice to identify the source of the allocations for Int128.

@omus
Copy link
Contributor

omus commented Nov 5, 2018

Reposting results:

Operation Values
identity ÷ + / *
Category Type time (ms) allocs time (ms) allocs time (ms) allocs time (ms) allocs time (ms) allocs
Int Int32 1.35 0 5.16 0 1.47 0 2.35 0 1.61 0
Int64 1.86 0 18.66 0 1.89 0 2.46 0 1.95 0
Int128 3.77 0 26.07 0 3.85 0 16.74 0 3.95 0
Float Float32 1.35 0 28.97 0 1.47 0 1.75 0 1.47 0
Float64 1.85 0 27.37 0 1.88 0 2.45 0 1.89 0
FixedDecimal FD{Int32,2} 1.35 0 5.16 0 1.48 0 38.20 0 31.73 0
FD{Int64,2} 1.86 0 18.75 0 1.89 0 59.18 0 47.03 0
FD{Int128,2} 1320.01 14000000 26.19 0 1324.35 14000000 7267.32 72879639 6139.13 62000000

@NHDaly
Copy link
Member Author

NHDaly commented Nov 5, 2018

(Note that after this PR, the benchmarks don't change. This is more like a minor optimization I discovered while researching the weird allocations. Maybe I'll open another issue for the benchmarks then separately!) :)

@NHDaly NHDaly mentioned this pull request Nov 5, 2018
3 tasks
@NHDaly
Copy link
Member Author

NHDaly commented Nov 5, 2018

(Opened #37 to discuss the weird allocation and other questions)

@omus omus merged commit d87debb into JuliaMath:master Nov 5, 2018
@NHDaly NHDaly deleted the copy-constructor branch November 5, 2018 23:16
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