朱莉娅:有效的内存分配

时间:2016-03-04 15:16:11

标签: memory julia

我的程序很耗费内存,所以我需要尽可能多地保存内存。 为变量分配整数值时,值的类型将始终为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?

1 个答案:

答案 0 :(得分:9)

你错过了树林。 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都无法再优化该函数并最终进行大量分配。我 高度 建议您在this very good blog postmanual's performance tips中详细了解类型稳定性。

至于使用哪种整数类型:只使用Int,除非你知道你将超过20亿。如果您知道需要支持大量数字,请使用BigInt。值得注意的是,创建类似的BigInt数组使用的内存明显少于"正确大小的"上面的数组:

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