Julia types newbie question

260 views
Skip to first unread message

angel.vice...@gmail.com

unread,
Oct 17, 2016, 9:19:51 AM10/17/16
to julia-users
Hi,

probably a very basic question, but I'm just starting to play around
with Julia types.

I was hoping to improve the performance of a little program I wrote, so
I decided to try Int32 integers instead of the default Int64, but if I
try to use sum, it seems that it is expecting Int64 and the result is
Int64, defeating the purpose of working with Int32 and actually making
the code much slower than the naive version.

,----
| julia> typeof(sum([i for i in Int32(1):Int32(100)])) |
| Int64
`----

Do I have to write down my own Int32::sum function? I assume I'm missing
something quite obvious?

Thanks,
--
Ángel de Vicente
http://www.iac.es/galeria/angelv/

Simon Danisch

unread,
Oct 17, 2016, 9:37:23 AM10/17/16
to julia-users
I'm guessing that is done to prevent overflow.
So you need to use your own implementation.
Here are the promote rules defining this behavior: https://github.com/JuliaLang/julia/blob/master/base/reduce.jl#L32
So in theory you could also implement your own Int type, that has a different promote behavior. Probably not worth it, though ;)

Angel de Vicente

unread,
Oct 17, 2016, 9:54:56 AM10/17/16
to julia...@googlegroups.com
Hi Simon,

Simon Danisch <sdan...@gmail.com> writes:

> I'm guessing that is done to prevent overflow.
> So you need to use your own implementation.
> Here are the promote rules defining this behavior: https://github.com/JuliaLang/julia/blob/master/base/reduce.jl#L32
> So in theory you could also implement your own Int type, that has a
> different promote behavior. Probably not worth it, though ;)

OK, thanks, I will check reduce.jl, I was just finding odd how the
promotion happens for some integer types and not others...

,----
| julia> typeof(sum([i for i in Int8(1):Int8(10)]))
| Int32
|
| julia> typeof(sum([i for i in Int16(1):Int16(10)]))
| Int32
|
| julia> typeof(sum([i for i in Int32(1):Int32(10)]))
| Int64
|
| julia> typeof(sum([i for i in Int64(1):Int64(10)]))
| Int64
|
| julia> typeof(sum([i for i in Int128(1):Int128(10)]))
| Int128
`----

Ismael Venegas Castelló

unread,
Oct 19, 2016, 2:55:56 AM10/19/16
to julia-users
You can do something like this:

C:\Users\Ismael                                                                          
λ julia5                                                                                 
               _                                                                         
   _       _ _(_)_     |  By greedy hackers for greedy hackers.                          
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org                       
   _ _   _| |_  __ _   |  Type "?help" for help.                                         
  | | | | | | |/ _' |  |                                                                 
  | | |_| | | | (_| |  |  Version 0.5.0 (2016-09-19 18:14 UTC)                           
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release                         
|__/                   |  x86_64-w64-mingw32                                             
                                                                                         
julia> Base.sum{T<:Real, S<:Real}(::Type{T}, xs::Range{S})::T = sum(xs)                  
                                                                                         
julia> r = 1:100; sum(r), sum(Int32, r), sum(Rational{Int16}, r), sum(Complex{BigInt}, r)
(5050,5050,5050//1,5050 + 0im)                                                           
                                                                                         
julia> for T ∈ (Int32, Rational{Int16}, Complex{BigInt})                                 
           @assert sum(T, 1:100) |> typeof == T                                          
       end                                                                               
                                                                                         
julia>                                                                                   

Angel de Vicente

unread,
Oct 21, 2016, 9:08:35 AM10/21/16
to julia...@googlegroups.com
Hi,

Ismael Venegas Castelló <ismael...@gmail.com> writes:
> julia> Base.sum{T<:Real, S<:Real}(::Type{T}, xs::Range{S})::T = sum(xs)
> julia> r = 1:100; sum(r), sum(Int32, r)

thanks for this, but as I understand it, for my particular case in which
I'm interested in working with 32bits Integers this would be similar to
just doing:

Int32(sum(1:100))

OK, the result will be of type Int32 but everything in between has been
calculated as Int64, right?

I wanted to see if there is any difference in speed when doing addition
(or any other operations) only with Int32 instructions (assuming I know
I won't get overflows).

Cheers,

Simon Danisch

unread,
Oct 21, 2016, 9:32:38 AM10/21/16
to julia-users
There is a speed difference, which you can see beautifully like this:


function _sum{T}(::Type{T}, A)
    r = zero(T)
    @inbounds for i in eachindex(A)
        r += T(A[i])
    end
    r
end

@code_llvm _sum(Int, rand(Int64, 10^6)) -> uses <4,Int64> vectors
@code_llvm _sum(Int, rand(Int32, 10^6)) -> uses <8,Int32> vectors
# this suggests that we can get a speed up, but if we get it still depends on the CPU we use.
using BenchmarkTools # so lets benchmark this
x = rand(Int32(1):Int32(10), 10^6)
@benchmark _sum($Int64, $x) # ~ 80μs
@benchmark _sum($Int32, $x) # ~ 50μs <- its faster!



Am Montag, 17. Oktober 2016 15:19:51 UTC+2 schrieb Ángel de Vicente:

Angel de Vicente

unread,
Oct 23, 2016, 2:02:58 PM10/23/16
to julia...@googlegroups.com
Hi Simon,

Simon Danisch <sdan...@gmail.com> writes:
> There is a speed difference, which you can see beautifully like this:
>
> function _sum{T}(::Type{T}, A)
> r = zero(T)
> @inbounds for i in eachindex(A)
> r += T(A[i])
> end
> r
> end
>

great, thanks. My machine seems to be way slower that yours or either I
run the benchmark with more elements, but certainly I can see a big
improvement if working only with Int32's:

,----
| julia> x32 = rand(Int32(1):Int32(10), 10^6)
|
| julia> x64 = rand(Int64(1):Int64(10), 10^6)
|
| julia> @benchmark _sum(Int32,x32)
| BenchmarkTools.Trial:
| samples: 9206
| evals/sample: 1
| time tolerance: 5.00%
| memory tolerance: 1.00%
| memory estimate: 16.00 bytes
| allocs estimate: 1
| minimum time: 529.80 μs (0.00% GC)
| median time: 534.73 μs (0.00% GC)
| mean time: 539.94 μs (0.00% GC)
| maximum time: 873.10 μs (0.00% GC)
|
| julia> @benchmark _sum(Int64,x64)
| BenchmarkTools.Trial:
| samples: 4159
| evals/sample: 1
| time tolerance: 5.00%
| memory tolerance: 1.00%
| memory estimate: 16.00 bytes
| allocs estimate: 1
| minimum time: 1.18 ms (0.00% GC)
| median time: 1.19 ms (0.00% GC)
| mean time: 1.20 ms (0.00% GC)
| maximum time: 1.72 ms (0.00% GC)
`----
Reply all
Reply to author
Forward
0 new messages