From 927617328115d791b93f980fe1023bff68d641e7 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Wed, 7 Nov 2018 18:18:12 -0500 Subject: [PATCH 1/2] Add `convert(::Type{T}, x::T) where {T<:FD} = x` This fixes unnecessary copies on `setindex!`, etc. --- src/FixedPointDecimals.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/FixedPointDecimals.jl b/src/FixedPointDecimals.jl index 79014c3..a1e57db 100644 --- a/src/FixedPointDecimals.jl +++ b/src/FixedPointDecimals.jl @@ -274,6 +274,8 @@ function round(::Type{FD{T, f}}, x::Rational, ::RoundingMode{:Nearest}=RoundNear end # conversions and promotions +convert(::Type{FD{T, f}}, x::FD{T, f}) where {T, f} = x # Converting an FD to itself is a no-op + function convert(::Type{FD{T, f}}, x::Integer) where {T, f} reinterpret(FD{T, f}, T(widemul(x, coefficient(FD{T, f})))) end From 54d2d5a22e01b9d86265554a27af4753c7c17d09 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Thu, 8 Nov 2018 10:46:32 -0500 Subject: [PATCH 2/2] Remove "copy constructor" after correct `convert` fix The "copy constructor" is no longer necessary now that a no-op `convert` is added, since by default construction falls back to convert. To verify, after this change, the performance is still correct: ``` julia> f = FixedPointDecimals.FixedDecimal{Int128,2}(3.25) FixedDecimal{Int128,2}(3.25) julia> @btime x = FixedPointDecimals.FixedDecimal{Int128, 2}($f) 0.036 ns (0 allocations: 0 bytes) FixedDecimal{Int128,2}(3.25) ``` And `@code_native` shows this to be a simple reinterpret. --- src/FixedPointDecimals.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/FixedPointDecimals.jl b/src/FixedPointDecimals.jl index a1e57db..866eb21 100644 --- a/src/FixedPointDecimals.jl +++ b/src/FixedPointDecimals.jl @@ -99,9 +99,6 @@ struct FixedDecimal{T <: Integer, f} <: Real _throw_storage_error(f, T, n) end end - - # Copy constructor -- prevents unneeded work to convert between the same types - FixedDecimal{T,f}(x::FixedDecimal{T,f}) where {T<:Integer,f} = new{T,f}(x.i) end @noinline function _throw_storage_error(f, T, n)