2017-09-30 1 views
1

가변 변수를 사용하면 메모리가 낭비 될 수 있는지 궁금합니다.변수로 변수를 전달하면 메모리가 낭비됩니까?

가 출력이 다음과 같은 두 가지 실시 예 (값 a, bc)를 고려 동일해야

// 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 

Example 1에서 각각의 기능은 가변 인수를 취하고 (I는 추정) 복사해야 그 논쟁의 총 3 부 작성합니다.

// Example 2 
let mutable mut = Map.empty 

mut <- mut |> Map.add "A" 0 
mut <- mut |> Map.add "B" 1 
mut <- mut |> Map.add "C" 2 

let fA (m: Map<string,int>) x = m.["A"] + x 
let fB (m: Map<string,int>) x = m.["A"] + m.["B"] + x 
let fC (m: Map<string,int>) x = m.["A"] + m.["B"] + m.["C"] + x 

let immut = mut 

let a = fA mut 0 // 0 
let b = fB mut 0 // 1 
let c = fC mut 0 // 3 

Example 2에서 각 함수는 동일한 불변의 인수를 복사합니다. 아마도 컴파일러는 이러한 복사본을 만들 때 추가 메모리를 사용하지 않을 정도로 똑똑합니다. 각 복사본에 대해 원래 개체에 대한 포인터 일 수 있습니다.

따라서 평균적으로 Example 1에 복사 된 개체가 Example 2에있는 불변 개체보다 작 으면 Example 2에 사용되는 메모리가 줄어 듭니다.

이 논리가 정확합니까?

+2

아니, 아무것도 이제까지 복사되지 않습니다. 참조가 가리키는 데이터 구조의 변경 가능성과 참조의 변경 가능성을 혼동하고 있습니다. –

답변

3

예에서 Map<'K, 'V> 값은 변경할 수 없으며 유일한 변경 가능 항목은 현재 Map<'K, 'V> 값의 인스턴스에 대한 참조를 유지하기 위해 사용하는 참조 mut입니다. 컴파일러는 값의 복사본을 만들 필요가 없습니다 (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 
관련 문제