gpt4 book ai didi

julia - Julia 有懒惰的 `filter` 吗?

转载 作者:行者123 更新时间:2023-12-04 22:54:45 29 4
gpt4 key购买 nike

在 Python 中可以使用 if在列表理解中过滤掉元素。在 Julia 中有一个懒惰的人 filter相等的?

for x in filter(x->x<2, 1:3)
println(x)
end

仅限作品和打印品 1但是 filter(x->x<2, 1:3)是急切的,因此可能不适合数十亿条记录。

最佳答案

您可以像在 Python 中一样执行此操作:

julia> function f()
for x in (i for i in 1:10^9 if i == 10^9)
println(x)
end
end
f (generic function with 1 method)

julia> @time f()
1000000000
3.293702 seconds (139.87 k allocations: 7.107 MiB)

julia> @time f()
1000000000
3.224707 seconds (11 allocations: 352 bytes)

你会看到它没有分配。但是在不使用生成器的情况下只在循环内执行过滤器测试会更快:
julia> function g()
for x in 1:10^9
x == 10^9 && println(x)
end
end
g (generic function with 1 method)

julia> @time g()
1000000000
2.098305 seconds (53.49 k allocations: 2.894 MiB)

julia> @time g()
1000000000
2.094018 seconds (11 allocations: 352 bytes)

编辑 最后你可以使用 Iterators.filter :
julia> function h()
for x in Iterators.filter(==(10^9), 1:10^9)
println(x)
end
end
h (generic function with 1 method)

julia>

julia> @time h()
1000000000
0.390966 seconds (127.96 k allocations: 6.599 MiB)

julia> @time h()
1000000000
0.311650 seconds (12 allocations: 688 bytes)

在这种情况下,这将是最快的(另请参阅 https://docs.julialang.org/en/latest/base/iterators/#Iteration-utilities-1 )。

您可能还想查看 https://github.com/JuliaCollections/IterTools.jl .

编辑 2

有时 Julia 比你想象的更强大。看一下这个:
julia> function g2()
for x in 1:1_000_000_000
x == 1_000_000_000 && println(x)
end
end
g2 (generic function with 1 method)

julia>

julia> @time g2()
1000000000
0.029332 seconds (62.91 k allocations: 3.244 MiB)

julia> @time g2()
1000000000
0.000636 seconds (11 allocations: 352 bytes)

我们看到编译器基本上编译了我们所有的计算。

本质上 - 在前面的例子中,常量传播开始并取代了 10^9来自 1_000_000_000Iterators.filter例子。

因此,我们必须设计一个更智能的测试。它是这样的:
julia> using BenchmarkTools

julia> function f_rand(x)
s = 0.0
for v in (v for v in x if 0.1 < v < 0.2)
s += v
end
s
end
f_rand (generic function with 1 method)

julia> function g_rand(x)
s = 0.0
for v in x
if 0.1 < v < 0.2
s += v
end
end
s
end
g_rand (generic function with 1 method)

julia> function h_rand(x)
s = 0.0
for v in Iterators.filter(v -> 0.1 < v < 0.2, x)
s += v
end
s
end
h_rand (generic function with 1 method)

julia> x = rand(10^6);

julia> @btime f_rand($x)
2.032 ms (0 allocations: 0 bytes)
14922.291597613703

julia> @btime g_rand($x)
1.804 ms (0 allocations: 0 bytes)
14922.291597613703

julia> @btime h_rand($x)
2.035 ms (0 allocations: 0 bytes)
14922.291597613703

现在我们得到了我最初期望的结果(带有 if 的普通循环是最快的)。

关于julia - Julia 有懒惰的 `filter` 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55240043/

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