Julia内存分配疑问:首次运行分配量为何远高于后续?
Julia内存分配疑问解答
问题描述
我正在尝试理解Julia中的内存分配,编写了如下测试代码:
function f() function test(x,y) return x-1,y+1 end x1=5 y1=6 function stest(num_runs,x,y) for i in 1:num_runs x,y=test(x,y) end return x,y end x1,y1=stest(10,x1,y1) println(x1,' ',y1) end @time begin f() end @time begin f() end
运行后得到如下输出:
-5 16 0.027611 seconds (20.59 k allocations: 1.039 MiB, 92.11% compilation time) -5 16 0.000077 seconds (18 allocations: 496 bytes)
请问为何会存在内存分配?且首次运行时的内存分配量为何如此之大?
原因解析
首次运行的大量分配:编译开销
Julia是**即时编译(JIT)**语言,首次执行函数时会触发完整的编译流程:
- 编译器要解析
f、嵌套的test和stest函数的代码,生成针对具体输入类型的优化机器码 - 编译过程中会分配内存存储抽象语法树(AST)、类型推断结果、机器码缓存等中间产物
- 输出里标注的
92.11% compilation time直接证明:大部分时间和内存都消耗在编译环节,而非代码的实际执行
后续运行的少量分配:IO与微小运行时开销
第二次运行时,函数已经完成编译并缓存了机器码,剩下的少量分配来自:
println的内部操作:比如字符串拼接、IO缓冲区的临时内存分配- 函数调用时的一些极小运行时结构(比如临时栈帧存储,但总量可以忽略)
验证:核心计算逻辑零分配
如果把println去掉,只保留计算逻辑,第二次运行的分配量会降到0。修改后的代码如下:
function f() function test(x,y) return x-1,y+1 end x1=5 y1=6 function stest(num_runs,x,y) for i in 1:num_runs x,y=test(x,y) end return x,y end return stest(10,x1,y1) end
此时第二次@time f()的输出会类似:
0.000002 seconds (0 allocations: 0 bytes)
这说明你的核心计算逻辑(test循环)本身完全没有内存分配,所有分配都来自编译阶段或IO操作。
内容的提问来源于stack exchange,提问作者codeenjoyer
相关产品推荐
相关产品推荐

