Generator expressions

I’m reading the Julia Manual on Generator Expressions.

According to the Manual … the following expression sums a series without allocating memory:

sum(1/n^2 for n in 1:1000)

So I tried to compare the previous expression with this other one, which, allegedly, consumes memory (it contains a list comprehension):

sum([1/n^2 for n in 1:1000])

Well, the result is exactly the opposite: have a look at what @time returns:

It seems to me that generator Expressions consume more than twice as much time and memory space than their List comprehensions counterparts.

I recommend using @btime from BenchmarkTools, which removes initial compilation from the benchmark and repeats the benmark multiple times. Here are the results I obtain with @btime:

julia> @btime sum(1/n^2 for n in 1:1000)
  3.178 μs (0 allocations: 0 bytes)
1.6439345666815615

julia> @btime sum([1/n^2 for n in 1:1000])
  1.806 μs (1 allocation: 7.94 KiB)
1.6439345666815612

I’m not sure why there is a time difference, but the memory problem is resolved.

6 Likes

If you look at the output of the timing, you see “99.63% compilation time”, which tells you that you are not measuring runtime.

6 Likes

notice that they have different results, so maybe they use different strategies

The difference in execution times is as expected for much larger ranges.
Probably for “narrow” ranges the overload of the generator function takes over (!?).
The sum method works very well with a function at the first argument.

julia> @btime sum([1/n^2 for n in 1:10^6])
  1.720 ms (2 allocations: 7.63 MiB)
1.6449330668487272

julia> @btime sum(1/n^2 for n in 1:10^6)
  853.000 μs (0 allocations: 0 bytes)
1.64493306684877

julia> @btime sum(n->1/n^2,1:10^6)
  445.200 μs (0 allocations: 0 bytes)
1.6449330668487272

And better yet it would do the following function :smile:

sumoneovern2(oneto=10^6)= oneto>10 ? 9.869604401089358/6 : sum([1/n^2 for n in 1:10])

ulia> @btime sumoneovern2(10^5)
  0.800 ns (0 allocations: 0 bytes)
1.6449340668482264
1 Like