f# 解释器运行的内存使用优化

问题描述 投票:0回答:2

我有一个很愚蠢的问题,但到目前为止我还没能回答。 我开始用 f# 编写一个小程序,只是为了用这种语言进行一些修改,我想到了一个问题:如果我编写一个可以这样总结的代码:

let a = 10  
let b = a

口译员将如何处理记忆?它会在堆栈中创建第二个空间,其中包含变量

b
的 10 还是仅指向变量
a
的同一内存?

我尝试运行这个简单的代码:

printf "before: %A\n" (GC.GetTotalMemory false) 
let a = 10 
printf "after: %A" (GC.GetTotalMemory false) 

//output
before: 72903520L
after: 72911712L

还有其他代码:

printf "before: %A\n" (GC.GetTotalMemory false) 
let a = 10
let b = a 
printf "after: %A" (GC.GetTotalMemory false) 

//output
before: 73000992L
after: 73009184L

由于差异很大,我不确定我选择的函数是否正确,因此我不知道如何解释这个结果。

memory memory-management f#
2个回答
0
投票

此代码具有值语义,这意味着

b
是用
a
的值初始化的,而不是对
a
所指向的位置的引用。您可以通过使
a
可变并在赋值后更改其值来验证这一点:

let mutable a = 10
let b = a
a <- 15
printfn $"{a}"   // 15
printfn $"{b}"   // 10

在 F# 中,大多数时候,您可以将这些视为独立的值,而不必担心它们是如何分配的。如果您使用的语言中“别名”很常见(例如,同一可变内存位置有两个不同的名称,如 C# 对象),那么函数式编程就更容易考虑。


0
投票

如果你的代码是本地的,就像这样

let f() = let a = 10 let b = a printfn "%d" b

let 绑定实际上根本不生成任何内存分配。编译器将其优化为
printfn "%d" 10

。 有一个

不错的工具
,可以让您探索编译器的功能。

© www.soinside.com 2019 - 2024. All rights reserved.