Because julia has a GC, I've found that the memory allocations are critical to performance (which is why I added some more information to the @time macro, and added a @timev (verbose) macro as well). It doesn't harm anything to use the @time macros (there's even one that returns the information as a tuple so you can store the information and do whatever you want with it), and you will be able to track down performance issues much quicker.
On Friday, June 19, 2015 at 10:45:56 AM UTC-4, Xiubo Zhang wrote: > > Thanks for the reply. > > I am aware of the @time macro. Just that I thought tic() and toc() are > adequate for this case as I am not concerned with the memory side of things > at the moment. I have also read the performance section in the manual, > which led me to doing the benchmarks with functions rather than writing > expressions in the REPL. > > Loops are faster than vectorized code in Julia, and a comprehension is >> essentially a loop. >> > > This is exactly what I was thinking before asking this question. I learnt > that de-vectorized loops should be faster than the vectorized version, but > wouldn't the developers of the language simply implement the ".^" in the > form of plain for loops to benefit from the better performance? Also it > does not explain why the comprehension version is 3 to 4 times faster than > the for loop version. > > What did I miss? > > On Friday, 19 June 2015 15:29:15 UTC+1, Mauro wrote: >> >> Loops are faster than vectorized code in Julia, and a comprehension is >> essentially a loop. Also checkout the convenient @time macro, it also >> reports memory allocation. Last, there is a performance section in the >> manual where a lot of this is explained. But do report back if you got >> more questions. Mauro >> >> >> On Fri, 2015-06-19 at 15:41, Xiubo Zhang <[email protected]> wrote: >> > I am rather new to Julia, so please do remind me if I missed anything >> > important. >> > >> > I was trying to write a function which would operate on the elements in >> an >> > array, and return an array. For the sake of simplicity, let's say >> > calculating the squares of an array of real numbers. I designed four >> > functions, each implementing the task using a different style: >> > >> > function tf1{T<:Real}(x::AbstractArray{T}) return r = x .^ 2 end # >> > vectorised power operator >> > function tf2{T<:Real}(x::AbstractArray{T}) r = Array(T, length(x)); for >> i >> > in 1:length(x) r[i] = x[i] ^ 2 end; return r end # plain for loop >> > function tf3{T<:Real}(x::AbstractArray{T}) return [i ^ 2 for i in x] >> end # >> > array comprehension >> > function tf4{T<:Real}(x::AbstractArray{T}) return map(x -> x ^ 2, x) >> end # >> > using the "map" function >> > >> > And I timed the operations with tic() and toc(). The results varies >> from >> > each run, but the following is a typical set of results after warming >> up: >> > >> > tic(); tf1( 1:1000000 ); toc() >> > elapsed time: 0.011582169 seconds >> > >> > tic(); tf2( 1:1000000 ); toc() >> > elapsed time: 0.016566094 seconds >> > >> > tic(); tf3( 1:1000000 ); toc() >> > elapsed time: 0.004038817 seconds >> > >> > tic(); tf4( 1:1000000 ); toc() >> > elapsed time: 0.065989988 seconds >> > >> > I understand that the map function should run slower than the rest, but >> why >> > is the comprehension version so much faster than the vectorised "^" >> > operator? Does this mean array comprehensions should be used in favour >> of >> > all other styles whenever possible? >> > >> > P.S. version of Julia: >> > _ >> > _ _ _(_)_ | A fresh approach to technical computing >> > (_) | (_) (_) | Documentation: http://docs.julialang.org >> > _ _ _| |_ __ _ | Type "help()" for help. >> > | | | | | | |/ _` | | >> > | | |_| | | | (_| | | Version 0.3.9 (2015-05-30 11:24 UTC) >> > _/ |\__'_|_|_|\__'_| | Official http://julialang.org/ release >> > |__/ | x86_64-w64-mingw32 >> > >> > This is on a Windows 7 machine. >> >>
