我的程序很耗费内存,所以我需要尽可能多地保存内存。 为变量分配整数值时,值的类型将始终为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?
答案 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 post和manual's performance tips中详细了解类型稳定性。
至于使用哪种整数类型:只使用Int
,除非你知道你将超过20亿。如果您知道需要支持大量数字,请使用BigInt
。值得注意的是,创建类似的BigInt
数组使用的内存明显少于"正确大小的"上面的数组:
julia> @allocated [big(i) for i=1:100]
6496