Arrays 使用数组视图时出现意外内存分配(julia)
我试图在数组X中搜索所需的模式(变量模板)。模板的长度为9 我在做一些事情,比如:Arrays 使用数组视图时出现意外内存分配(julia),arrays,performance,julia,allocation,Arrays,Performance,Julia,Allocation,我试图在数组X中搜索所需的模式(变量模板)。模板的长度为9 我在做一些事情,比如: function check_alloc{T <: ZeroOne}(x :: AbstractArray{T}, temp :: AbstractArray{T}) s = 0 for i in 1 : 1000 myView = view(x, i : i + 9) if myView == temp s += 1
function check_alloc{T <: ZeroOne}(x :: AbstractArray{T}, temp :: AbstractArray{T})
s = 0
for i in 1 : 1000
myView = view(x, i : i + 9)
if myView == temp
s += 1
end
end
return s
end
function check\u alloc{T这至少适用于任意大小的temp
和x
但仍有~KB的分配
function check_alloc{T}(x :: AbstractArray{T}, temp :: AbstractArray{T})
s = 0
pl = length(temp)
for i in 1:length(x)-pl+1
@views if x[i:i+pl-1] == temp
s += 1
end
end
return s
end
编辑:正如@Sairus在评论中所建议的,我们可以本着以下精神做一些事情:
function check_alloc2{T}(x :: AbstractArray{T}, temp :: AbstractArray{T})
s = 0
pl = length(temp)
plr = 1:pl
for i in 1:length(x)-pl+1
same = true
for k in plr
@inbounds if x[i+k-1] != temp[k]
same = false
break
end
end
if same
s+=1
end
end
return s
end
这没有分配:
julia> using BenchmarkTools
julia> a = collect(1:1000);
julia> b = collect(5:12);
julia> @btime check_alloc2($a,$b);
1.195 μs (0 allocations: 0 bytes)
您获得分配的原因是view(A,i:i+9)
创建了一个称为子数组的小对象。这只是一个“包装器”,基本上存储了对A
的引用和您传入的索引(i:i+9
)。因为包装器很小(对于一维对象约40字节),有两种合理的存储方法:““分配”仅指堆内存,因此如果Julia可以将包装器存储在堆栈上,它将报告没有分配(而且速度更快)
不幸的是,目前一些子阵列
对象(截至2017年底)必须存储在堆上。原因是Julia是一种语言,这意味着如果a
是一个不再使用的堆分配对象,那么a
可能会从内存中释放。关键点是:当前,只有当这些变量存储在因此,如果所有子数组都存储在堆栈上,那么您将遇到如下代码问题:
function create()
A = rand(1000)
getfirst(view(A, 1:10))
end
function getfirst(v)
gc() # this triggers garbage collection
first(v)
end
由于create
在调用getfirst
后不会再次使用A
,因此它不会“保护”A
。风险在于gc
调用可能会释放与A
相关的内存(从而中断v
本身中条目的任何使用,因为v
依赖于A
),除非使用v
可以防止A
被垃圾收集。但目前,堆栈分配的变量无法保护堆分配的内存:垃圾收集器只扫描堆上的变量
您可以使用您的原始函数来观察这一点,通过去掉(不相关,出于这些目的)将其修改为限制性稍小一些t什么是ZeroOne
?另外,您说您正在搜索的模式长度为9,但您正在创建一个长度为10的视图i:i+9
。这不是关于视图
,而是=
操作(您可以注释掉它并查看@time
)。您可以手动重写此比较或查看@edit>(==)(AbstractArray[],AbstractArray[])
也许还可以看看ZeroOne是联合体{Bool,Int8,UInt8}。视图的确不需要内存来创建,但为什么(==)操作这么慢?为什么需要这么多内存?==
没有创建临时数组,但是==
创建了。非常感谢!我对这种情况完全感到困惑。(==)真的需要它吗分配这么多内存的操作?感谢您分享关于幕后发生的事情的深入知识。从-。
function check_alloc(x::AbstractArray{T}, temp::AbstractArray{T}) where T
s = 0
for i in 1 : 1000
myView = view(x, i : i + 9)
if myView == temp
s += 1
end
end
return s
end
a = collect(1:1010); # this uses heap-allocated memory
b = collect(1:10);
@time check_alloc(a, b); # ignore the first due to JIT-compilation
@time check_alloc(a, b)
a = 1:1010 # this doesn't require heap-allocated memory
@time check_alloc(a, b); # ignore due to JIT-compilation
@time check_alloc(a, b)
julia> @time check_alloc(a, b)
0.000022 seconds (1.00 k allocations: 47.031 KiB)
julia> @time check_alloc(a, b)
0.000020 seconds (4 allocations: 160 bytes)