gpt4 book ai didi

generator - 试图找到一种方法来构造 Julia `generator`

转载 作者:行者123 更新时间:2023-12-03 13:56:16 29 4
gpt4 key购买 nike

我是 Julia 的新手。
我主要用python编程。

在 python 中,
如果你想迭代大量的值,
通常构造一个所谓的生成器来节省内存使用。
这是一个示例代码:

def generator(N):
for i in range(N):
yield i

我想知道 Julia 是否有类似的东西。
在阅读了 Julia 手册后,
@task 宏似乎与 python 中的生成器具有相同(或相似)的功能。
然而,
经过一些实验,
内存使用量似乎比 julia 中的普通数组大。

我用 @time在 IJulia 中查看内存使用情况。
这是我的示例代码:

[更新]:添加 generator的代码方法
( generator 方法)
function generator(N::Int)
for i in 1:N
produce(i)
end
end

(发电机版)
function fun_gener()
sum = 0
g = @task generator(100000)
for i in g
sum += i
end
sum
end
@time fun_gener()耗时:0.420731828 秒(分配了 6507600 字节)

(阵列版)
function fun_arry()
sum = 0
c = [1:100000]
for i in c
sum += i
end
sum
end
@time fun_arry()耗时:0.000629629 秒(分配了 800144 字节)

谁能告诉我为什么 @task在这种情况下需要更多空间吗?
如果我想在处理大量值时节省内存使用量,
我能做些什么?

最佳答案

我推荐 "tricked out iterators" Carl Vogel 的博文,详细讨论了 julia 的迭代器协议(protocol)、任务和协同例程。
另见 task-aka-coroutines在 Julia 文档中。

在这种情况下,您应该使用 Range 类型(它定义了 迭代器协议(protocol) ):

julia> function fun_arry()
sum = 0
c = 1:100000 # remove the brackets, makes this a Range
for i in c
sum += i
end
sum
end
fun_arry (generic function with 1 method)

julia> fun_arry() # warm up
5000050000

julia> @time fun_arry()
elapsed time: 8.965e-6 seconds (192 bytes allocated)
5000050000
分配的内存更快且更少(就像 python 2 中的 xrange 一样)。
来自博文的片段:

From https://github.com/JuliaLang/julia/blob/master/base/range.jl, here’s how a Range’s iterator protocol is defined:

start(r::Ranges) = 0
next{T}(r::Range{T}, i) = (oftype(T, r.start + i*step(r)), i+1)
next{T}(r::Range1{T}, i) = (oftype(T, r.start + i), i+1)
done(r::Ranges, i) = (length(r) <= i)

Notice that the next method calculates the value of the iterator in state i. This is different from an Array iterator, which just reads the element a[i] from memory.

Iterators that exploit delayed evaluation like this can have important performance benefits. If we want to iterate over the integers 1 to 10,000, iterating over an Array means we have to allocate about 80MB to hold it. A Range only requires 16 bytes; the same size as the range 1 to 100,000 or 1 to 100,000,000.



您可以编写生成器方法(使用任务):
julia> function generator(n)
for i in 1:n # Note: we're using a Range here!
produce(i)
end
end
generator (generic function with 2 methods)

julia> for x in Task(() -> generator(3))
println(x)
end
1
2
3
注意:如果你用这个替换 Range,性能会差很多(并且分配更多的内存):
julia> @time fun_arry()
elapsed time: 0.699122659 seconds (9 MB allocated)
5000050000

关于generator - 试图找到一种方法来构造 Julia `generator`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29338914/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com