What does "better" mean in this context, style or speed? For me map is
better style (but that is of course subjective), but it also appears to
be in the range of push! with respect to speed within measurement noise
and allocates less (unless I am using push! incorrectly):

function give_funs1(n)
  funs = []
  for i in 1:n
    funs = [funs, () -> i]
  end
  funs
end

function give_funs2(n)
  map((i) -> (() -> i), 1:n)
end

function give_funs3(n)
  result = Any[]
  for i in 1:n
    push!(result, () -> i)
  end
  result
end

@time give_funs1(100000);
@time give_funs2(100000);
@time give_funs3(100000);

julia> @time give_funs1(100000);
elapsed time: 31.811824021 seconds (40187982672 bytes allocated, 69.98% gc time)

julia> @time give_funs2(100000);
elapsed time: 0.018686499 seconds (7992040 bytes allocated)

julia> @time give_funs3(100000);
elapsed time: 0.030754734 seconds (10890064 bytes allocated, 82.97% gc time)

Note that gc of course is idiosyncratic in this case and dominates the
measurement, and can occur for both 2 and 3.

Best,

Tamas

On Fri, Oct 17 2014, Tim Holy wrote:

> As for the accumulation, far better than either is to use push!.
>
> --Tim
>
> On Friday, October 17, 2014 09:48:49 AM Tamas Papp wrote:
>> I am not sure if I understood the question, but if the purpose is to
>> store the function you created before accumulating it in a list, you
>> could use
>> 
>> function give_funs()
>>   funs = []
>>   for i in 1:5
>>     newfun = () -> i
>>     funs = [funs, newfun]
>>   end
>>   funs
>> end
>> 
>> Also, accumulating the vector by concatenation may not be idiomatic in
>> this case. A more compact way would be
>> 
>> function give_funs()
>>   map((i) -> (() -> i), 1:5)
>> end
>> 
>> Best,
>> 
>> Tamas
>> 
>> On Thu, Oct 16 2014, Evan Pu <[email protected]> wrote:
>> > Consider this code:
>> > 
>> > function give_funs()
>> > 
>> >   funs = []
>> >   for i in 1:5
>> >   
>> >     function newfun()
>> >     
>> >       i
>> >     
>> >     end
>> >     funs = [funs, newfun]
>> >   
>> >   end
>> >   funs
>> > 
>> > end
>> > 
>> > The intention is to create 5 functions and store them in a list called
>> > "funs".
>> > All the functions take no argument, and when the ith function is called,
>> > it
>> > returns i.
>> > 
>> > However, when run...
>> > funs1 = give_funs()
>> > funs1[1]() # this should give 1, but instead it gives 5
>> > funs1[2]() # this should give 2, but instead it gives 5 as well
>> > 
>> > This is problem goes away if I stop naming the function as "newfun" but
>> > instead use ananymous functions like so:
>> > funs = [funs, () -> i]
>> > however in real code I would like to give it a name so to be more clear
>> > what the function is suppose to compute
>> > 
>> > It seems that these functions are bound by their function names, and since
>> > they're all named "newfun", the compiler over-write the old ones defined
>> > earlier.
>> > 
>> > How should this be resolved?

Reply via email to