Julia types newbie question

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Julia types newbie question

Angel de Vicente
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/         
Reply | Threaded
Open this post in threaded view
|

Re: Julia types newbie question

Simon Danisch
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 ;)


Am Montag, 17. Oktober 2016 15:19:51 UTC+2 schrieb Ángel de Vicente:
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
<a href="http://www.iac.es/galeria/angelv/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.iac.es%2Fgaleria%2Fangelv%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHWgWJwB7xZkScAhM-XaTehlCOVww&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.iac.es%2Fgaleria%2Fangelv%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHWgWJwB7xZkScAhM-XaTehlCOVww&#39;;return true;">http://www.iac.es/galeria/angelv/          
Reply | Threaded
Open this post in threaded view
|

Re: Julia types newbie question

Angel de Vicente
Hi Simon,

Simon Danisch <[hidden email]> 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    
`----

--
Ángel de Vicente
http://www.iac.es/galeria/angelv/         
Reply | Threaded
Open this post in threaded view
|

Re: Julia types newbie question

Ismael Venegas Castelló
In reply to this post by Angel de Vicente
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>                                                                                   



El lunes, 17 de octubre de 2016, 8:19:51 (UTC-5), Ángel de Vicente escribió:
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
<a href="http://www.iac.es/galeria/angelv/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.iac.es%2Fgaleria%2Fangelv%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHWgWJwB7xZkScAhM-XaTehlCOVww&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.iac.es%2Fgaleria%2Fangelv%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHWgWJwB7xZkScAhM-XaTehlCOVww&#39;;return true;">http://www.iac.es/galeria/angelv/          
Reply | Threaded
Open this post in threaded view
|

Re: Julia types newbie question

Angel de Vicente
Hi,

Ismael Venegas Castelló <[hidden email]> 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,
--
Ángel de Vicente
http://www.iac.es/galeria/angelv/         
Reply | Threaded
Open this post in threaded view
|

Re: Julia types newbie question

Simon Danisch
In reply to this post by Angel de Vicente
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:
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
<a href="http://www.iac.es/galeria/angelv/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.iac.es%2Fgaleria%2Fangelv%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHWgWJwB7xZkScAhM-XaTehlCOVww&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.iac.es%2Fgaleria%2Fangelv%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHWgWJwB7xZkScAhM-XaTehlCOVww&#39;;return true;">http://www.iac.es/galeria/angelv/          
Reply | Threaded
Open this post in threaded view
|

Re: Julia types newbie question

Angel de Vicente
Hi Simon,

Simon Danisch <[hidden email]> 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)
`----


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