朱莉娅:有效的内存分配

皮格纳

我的程序需要大量内存,因此我需要尽可能多地保存内存。当您为变量分配整数值时,该值的类型将始终为Int64,无论是0还是+ 2 ^ 63-1或-2 ^ 63。我找不到有效分配内存的聪明方法,所以我写了一个看起来像这样的函数(在本例中为整数):

function right_int(n)
    types = [Int8,Int16,Int32, Int64, Int128]
    for t in reverse(types)
        try
            n = t(n)
        catch InexactError
            break
        end
    end
    n
end

a = right_int(parse(Int,eval(readline(STDIN))))

但是我不认为这是个好方法。

我还有一个相关的问题:用数字运算而不担心typemins和typemaxs的有效方法是什么?将每个操作数转换为BigInt,然后应用right_int?

博曼

您错过了树木的森林。right_int键入不稳定类型稳定性是减少分配并使Julia快速运行的关键概念。通过尝试“调整大小”整数以节省空间,实际上会导致更多分配和更多内存使用。作为一个简单的示例,让我们尝试制作一个1到100的100个整数的“大小合适”的数组。它们都足够小以适合Int8,所以只有100个字节加上数组头,对吗?

julia> @allocated [right_int(i) for i=1:100]
26496

哇,26,496个字节!为什么那没用?为什么会有这么多的开销?关键是Julia无法推断出right_int可能的类型,因此它必须支持返回的任何类型:

julia> typeof([right_int(i) for i=1:100])
Array{Any,1}

这意味着Julia不能将整数密集地打包到数组中,而是将它们表示为指向100个单独的“装箱”整数的指针。这些框告诉Julia如何解释它们包含的数据,这会花费大量的开销。这也不仅影响数组-每当您right_int在任何函数中使用结果时,Julia都无法再优化该函数并最终进行大量分配。强烈建议您在此非常好的博客文章手册的性能提示中阅读有关类型稳定性的更多信息

至于要使用哪种整数类型:Int除非知道将要超过20亿,否则请使用如果您知道需要大量支持,请使用BigInt值得注意的是,创建类似的数组BigInt使用的内存要比上面的“大小合适”的数组少得多:

julia> @allocated [big(i) for i=1:100]
6496

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章