Memory 将可变变量作为参数传递会浪费内存吗?

Memory 将可变变量作为参数传递会浪费内存吗?,memory,f#,immutability,mutable,Memory,F#,Immutability,Mutable,我想知道使用可变变量是否会导致内存浪费 考虑以下两个示例,它们的输出(值a、b和c)应该相同: // Example 1 let mutable mut = Map.empty mut <- mut |> Map.add "A" 0 let fA (m: Map<string,int>) x = m.["A"] + x let a = fA mut 0 // 0 mut <- mut |> Map.add "B" 1 let fB (m: Map<

我想知道使用可变变量是否会导致内存浪费

考虑以下两个示例,它们的输出(值
a
b
c
)应该相同:

// Example 1

let mutable mut = Map.empty

mut <- mut |> Map.add "A" 0
let fA (m: Map<string,int>) x = m.["A"] + x
let a = fA mut 0 // 0

mut <- mut |> Map.add "B" 1
let fB (m: Map<string,int>) x = m.["A"] + m.["B"] + x
let b = fB mut 0 // 1

mut <- mut |> Map.add "C" 2
let fC (m: Map<string,int>) x = m.["A"] + m.["B"] + m.["C"] + x
let c = fC mut 0 // 3
示例2中
每个函数都复制相同的不可变参数。 据推测,编译器足够聪明,在制作这些副本时不会使用任何额外的内存。对于每个副本,它可能只是指向原始对象的指针

因此,即使在
示例1
中复制的对象平均比
示例2中的不可变对象小,在
示例2中使用的内存也会更少


这个推理正确吗?

在您的示例中,
Map
值是不可变的,唯一可变的是引用
mut
,您用来保留对
Map
值的当前实例的引用。编译器不需要复制值(我认为不存在F#编译器会在你背后复制值的情况——除了值类型)

这意味着您的两个示例几乎相同-唯一真正的区别是,在示例2中,您将向三个函数传递一个包含更多值的映射,因此查找可能会稍微长一点(但这充其量只是一个理论问题)

如果使用可变数据结构(调整数组大小)和显式复制按如下方式实现代码,则可能会出现您暗示的问题:

let data = ResizeArray<string * int>()

data.Add("A", 0)
let f1 = 
  let lookup = dict data 
  fun x -> lookup.[x]

data.Add("B", 1)
let f2 = 
  let lookup = dict data 
  fun x -> lookup.[x]

f1 "A" // = 0
f1 "B" // error
f2 "A" // = 0
f2 "B" // = 1
let data=ResizeArray()
数据。添加(“A”,0)
设f1=
让lookup=dict数据
乐趣x->查找[x]
数据。添加(“B”,1)
设f2=
让lookup=dict数据
乐趣x->查找[x]
f1“A”/=0
f1“B”//错误
f2“A”//=0
f2“B”//=1

不,任何内容都不会被复制。您将引用的可变性与引用所指向的数据结构的可变性混为一谈。
let data = ResizeArray<string * int>()

data.Add("A", 0)
let f1 = 
  let lookup = dict data 
  fun x -> lookup.[x]

data.Add("B", 1)
let f2 = 
  let lookup = dict data 
  fun x -> lookup.[x]

f1 "A" // = 0
f1 "B" // error
f2 "A" // = 0
f2 "B" // = 1