我的程序很耗费内存,所以我需要尽可能多地保存内存.为变量分配整数值时,值的类型将始终为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))))
Run Code Online (Sandbox Code Playgroud)
但我不认为这是一个很好的方法.
我还有一个相关的问题:什么是一种有效的数字操作方式而不用担心typemins和typemaxs?将每个操作数转换为BigInt然后应用right_int?
你错过了森林里的树木. right_int是不稳定的.类型稳定性是减少分配和使Julia快速运转的关键概念.通过尝试"缩小"整数来节省空间,实际上会导致更多的分配和更高的内存使用.举个简单的例子,让我们尝试从1-100开始制作一个100个整数的"正确大小"的数组.它们都小到可以放入Int8,所以只有100个字节加上数组头,对吧?
julia> @allocated [right_int(i) for i=1:100]
26496
Run Code Online (Sandbox Code Playgroud)
哇,26,496字节!为什么没那个工作?为什么会有这么多开销呢?关键是Julia无法推断出类型right_int可能是什么,所以它必须支持返回的任何类型:
julia> typeof([right_int(i) for i=1:100])
Array{Any,1}
Run Code Online (Sandbox Code Playgroud)
这意味着Julia无法将整数密集地打包到数组中,而是将它们表示为指向100个单独"盒装"整数的指针.这些框告诉Julia如何解释它们包含的数据,这需要相当多的开销.这不仅会影响数组 - 任何时候right_int在任何函数中使用结果时,Julia都无法再优化该函数并最终进行大量分配.我强烈建议您在这篇非常好的博客文章和手册的性能提示中阅读有关类型稳定性的更多信息.
至于使用哪种整数类型:只要使用,Int除非你知道你将超过20亿.如果您知道需要支持大量数字,请使用BigInt.值得注意的是,创建类似的BigInt使用数组的内存明显少于上面的"正确大小"数组:
julia> @allocated [big(i) for i=1:100]
6496
Run Code Online (Sandbox Code Playgroud)