optimization - Julia 代码优化,结构和原始类型之间的区别?(内存分配)
问题描述
我有一些代码可以优化一些我不希望 gc 触发内存分配的关键部分。
更准确地说,我有一个实数类型
struct AFloat{T<:AbstractFloat} <: Real
value::T
j::Int
end
我必须跟踪以执行自动微分。因此,对于任何算术运算,我都必须在磁带上进行一些注册。性能在这里非常重要(如果您在每个算术运算中再分配一个分配器,这会产生真正的不同!)。我可以选择AFloat{T}
或简单地使用原始类型来跟踪索引 j:
primitive type AFloat64 <: Real sizeof(Int) end
但是,我对这些结果感到困惑:
第一部分:好的
using BenchmarkTools
struct A n::Int64 end
vA=A[A(1)];
@time push!(vA,A(2))
v=Int64[1];
@time push!(v,2)
返回
0.000011 seconds (6 allocations: 224 bytes)
0.000006 seconds (5 allocations: 208 bytes)
这与以下内容一致:
@btime push!(vA,A(2))
@btime push!(v,2)
返回
46.410 ns (1 allocation: 16 bytes)
37.890 ns (0 allocations: 0 bytes)
-> 我会得出结论,与结构相比,推动原始类型避免了一次内存分配(对吗?)
第二部分:……有问题……?!
在这里我很困惑,我无法解释这些结果:
foo_A() = A(1);
foo_F64() = Float64(1.);
foo_I64() = Int64(1);
@time foo_A()
@time foo_F64()
@time foo_I64()
返回
0.000004 seconds (5 allocations: 176 bytes)
0.000005 seconds (5 allocations: 176 bytes)
0.000005 seconds (4 allocations: 160 bytes)
Q1 如何解释差异 foo_F64() vs foo_I64() (5 allocs vs 4 allocs)?
此外,结果似乎与@btime 输出不一致:
@btime foo_A()
3.179 ns (0 allocations: 0 bytes)
@btime foo_F64()
3.801 ns (0 allocations: 0 bytes)
@btime foo_I64()
3.180 ns (0 allocations: 0 bytes)
Q2:@time 或@btime 的正确答案是什么?为什么?
综合来说,在 Julia 中, foo_A和foo_Primitive在性能和内存分配方面是否存在差异,其中:
struct A n::Int64 end
foo_A() = A(1)
foo_Primitive() = Int64(1)
我知道使用@time 或@btime 时,使用如此小的表达式确实存在副作用的风险。理想情况下,最好了解 Julia 的内部知识来回答。但我不
julia> versioninfo()
Julia Version 0.6.2
Commit d386e40c17 (2017-12-13 18:08 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Xeon(R) CPU E5-2603 v3 @ 1.60GHz
WORD_SIZE: 64
BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
LAPACK: libopenblas64_
LIBM: libopenlibm
LLVM: libLLVM-3.9.1 (ORCJIT, haswell)
解决方案
您看到的分配只是 REPL afaict 时间的副作用。
如果你把它们放在一个函数中,那么无论你使用的是结构体还是原始类型,分配都是一样的:
julia> function f()
vA=[A(1)]
@time push!(vA,A(2))
v=[1]
@time push!(v,2)
end
f (generic function with 1 method)
julia> f();
0.000000 seconds (1 allocation: 32 bytes)
0.000000 seconds (1 allocation: 32 bytes)
推荐阅读
- c# - 将 C# MVC 模型数据中的直接 HTML 显示到 CSHTML 页面?或添加 HTML 换行符服务器端?
- group-by - PySpark:groupBy 两列,变量分类并按升序排序
- java - 如何正确膨胀以尊重视图层次结构?
- sql - 使用 CTE 获取 emp 的层次结构,无论职位如何
- python-3.x - 训练贝叶斯分类器
- pandas - 如何使用 scipy 优化曲线拟合与熊猫 df
- jquery - Django JQuery Ajax 事件未触发
- c# - 在 C# 中获取 ODATA 元素名称和数据类型或迭代 EdmCollectionType
- amazon-web-services - Python 时区仅使用 AWS Lambda 中可用的模块?
- python - Python计算字典中的副本