2011-08-19 4 views
5

성능 측면에서 '직접'여러 번 배열 요소에 액세스하거나 해당 값을 변수에 할당하고 해당 변수를 사용하는 것이 더 낫습니까? 다음 코드에서 여러 번 값을 참조한다고 가정합니다.직접 배열 요소에 액세스하는 것과 변수에 할당하는 것

이 질문에 대한 추론은 배열 요소에 액세스 할 때마다 여분의 공간을 필요로하지 않고 수행 할 때마다 약간의 컴퓨팅 비용이 필요하다는 것입니다. 반면에 값을 변수에 저장하면이 액세스 비용이 제거되지만 추가 공간이 필요합니다.

// use a variable to store the value 
Temp = ArrayOfValues(0) 
If Temp > 100 Or Temp < 50 Then 
    Dim Blah = Temp 
    ... 

// reference the array element 'directly' 
If ArrayOfValues(0) > 100 Or ArrayOfValues(0) < 50 Then 
    Dim Blah = ArrayOfValues(0) 
    ... 

나는 우리가 어느 시점에서 (값이 여러 번 참조 할 것) 실제 사용에서 큰 규모에 대해 얘기하고 이것은 사소한 예를 알지만, 가정은 시간과 공간의 가치를 계산 사이의 트레이드 오프입니다 고려한다면 (전혀)?

+1

최적화 컴파일러는 HLL에 대해 완전히 부끄러워 할 것입니다. 어셈블리를 사용하거나 최적화를 해제 한 경우 레지스터는 캐시보다 빠르기 때문에 자주 사용하는 값을 가능한 많이 레지스터에로드해야합니다. 일반적으로 레지스터 압박과 메모리 계층 사이의 전환점은 아마도 경험적 문제 일 것이라고 생각합니다. – Patrick87

답변

2

참조 유형의 경우 포인터 (2 바이트)이고 대부분의 값 유형은 단지 몇 바이트 만 필요하기 때문에 메모리 소비의 오버 헤드는 매우 제한됩니다.

배열은 대부분의 언어에서 매우 효율적인 구조입니다. 인덱스를 얻는 것은 조회를 포함하지 않고 단지 일부 수학을 포함합니다 (각 배열 슬롯은 4 바이트를 차지하므로 11 번째 슬롯은 40 오프셋에 있습니다). 그런 다음 경계 검사에 약간의 오버 헤드가있을 수 있습니다. 새 로컬 변수에 메모리를 할당하고이를 해제하려면 약간의 CPU 사이클이 필요합니다. 결국 결국 로컬 var에 복사하여 제거하는 배열 조회 수에 따라 달라집니다.

사실 정말 예외적으로 하드웨어가 필요하거나 실제로 큰 루프가 필요하고 실제로 테스트를 거쳐야합니다. 개인적으로 코드를 더 읽기 쉽게 만들어 주므로 개별 변수를 자주 선택합니다. 로컬 VAR을 만들기 전에이 배열 조회를 할 수 있기 때문에

귀하의 예 BTW 홀수 : 이 더 의미 (제거 2 명 조회)

Dim blah = ArrayOfValues(0) 
if blah > 100 or blah < 50 then 
... 
2

이 태그가 언어 무신론자,하지만 난 돈을 만든다 그것이 사실이라고 생각하지 않습니다. 이 게시물은 질문의 C 및 C++ 버전에 대한 답변입니다.

최적화 컴파일러는 "알몸"배열 액세스를 처리 할 수 ​​있습니다. C 또는 C++에서 함수가 호출되지 않으면 컴파일러가 메모리 위치의 값을 기억하지 못할 것이라고 생각할 필요가 없습니다. 예 : myArray의 단지 [] (int)로 정의되어 있지만 실제로 뭔가하지 않을 경우

int a = myarray[19]; 
int b = myarray[19] * 5; 
int c = myarray[19]/2; 
int d = myarray[19] + 3; 

그러나, 또 다른 번역 단위에 정의 된 함수 operator[]()와 "공상"특히 일부 사용자 정의 컨테이너 유형, 그 기능은 해야합니다 값이 요청 될 때마다 호출됩니다 (함수가 메모리의 위치에서 데이터를 반환하고 로컬 함수는 함수의 결과가 상수가되도록 의도했기 때문에이를 호출하지 않습니다).

비록 '누드'배열이라 할지라도, 함수 호출을 통해 같은 것을 여러 번 접근한다면, 컴파일러는 유사하게 값이 변경되었다고 가정해야합니다 (주소 자체를 기억할 수 있다고하더라도). 예 : 컴파일러에서 myArray [19] 이전과 함수 호출 후 동일한 값을가집니다 것을 알 수있는 방법은 없습니다

int a = myarray[19]; 
NiftyFunction(); 
int b = myarray[19] * 8; 

.

따라서 일반적으로 값이 로컬 범위를 통해 일정하다는 것을 알고 있으면이를 로컬 변수에 "캐시"합니다. 당신은 방어 프로그램과 당신이 일에 넣었습니다이 조건을 검증하기 위해 주장을 사용할 수 있습니다

int a = myarray[19]; 
NiftyFunction(); 
assert(myarray[19] == a); 
int b = a * 8; 

마지막 이점은 어딘가에 배열에 묻혀하지 않는 경우는 디버거의 값을 검사하는 것이 훨씬 쉽다이다 .

+1

+1 "이것은 태그가있는 언어에 의존하지 않지만 실제로는 그렇게 생각하지 않습니다." C# 응답은 특정 방식으로 다를 수 있지만, 나는 그것을 제공하기에는 자격이 없습니다. – ClickRick

관련 문제