2008-11-04 5 views
19

JavaScript에서 this와 같은 for 루프를 만드는 것은 알고 있습니다. for(int i = 0; i < arr.length; i++)은 매번 배열 길이를 계산할 때 값이 비쌉니다. 이 동작은 목록 및 배열에서도 C#에서 비용이 많이 듭니다. 아니면 컴파일 시간에 최적화되어 있습니까? 또한 Java와 같은 다른 언어는 어떻게 처리합니까?루프에서 array.length 또는 list.count를 수행하는 데 비용이 많이 듭니까

답변

26

아니요,은 C#으로 값이 쌉니다. 첫 번째로, "계산"이 없습니다. 길이를 쿼리하는 것은 기본적으로 인라이닝 덕분에 기본적인 작업입니다. 둘째, (according to its developers)이기 때문에 컴파일러는이 액세스 패턴을 인식하고 실제로 배열 요소 액세스에 대한 모든 (중복) 경계 검사를 최적화합니다.

그런데 나는 현대의 자바 스크립트 가상 머신에서 비슷한 것이 사실이라고 생각합니다. 아직 그렇지 않다면 이것은 사소한 최적화이기 때문에 곧 될 것입니다.

+1

인라인, 인라인이란 무엇입니까? – maxfridbe

+0

오타입니다. ;-) 감사. –

+0

자바 스크립트의 경우 IE에서 "(var i = 0, mi = arr.length; i Sciolist

3

거의 모든 언어에서 답변은 "의존적"입니다.

대부분의 경우 컴파일러가 루프에있는 동안 목록이나 배열의 길이가 변경 될 수 있는지 여부를 판단 할 수 있는지 여부에 달려 있습니다.

그래도 언어 사양에 의해 정의되지는 않습니다.

그래서 컴파일로는 이해할 수 없을 수도 있습니다. 객체의 길이가 변하지 않는다고 정말로 생각한다면 길이를 먼저 계산하고 루프 제어 구조에서 자유롭게 사용하십시오. 이 자바와 같은 아무것도 있다면

그러나 다른 스레드의 조심

...

+0

글쎄, C#과 같은 언어에 대한 답변은 명확하게 문서화 된 동작이므로 "의존적"이 아닙니다. –

0

:

는 I 도움 아래의 링크를 발견했다.

5
  1. 모든 .Net 배열에는 배열의 길이가 포함 된 필드가 있으므로 길이는 사용시 계산시 생성되지 않습니다.

  2. 닷넷 가상 머신은 가능할 때마다 경계 검사를 제거하는 데 매우 뛰어납니다. 경계 검사가 루프 외부로 이동하는 경우 중 하나입니다 (대부분의 상황에서 오버 헤드가 2 오버 헤드 인 경우) .

편집 : 당신이 Linq에가() 확장 메서드를 카운트 사용하는 경우

Array Bounds Check Elimination

+0

Rez, 미안하지만 이것에 대한 출처가 있습니까? –

+1

@JacobStamm 편집 내역보기 –

0

나는 다음은이 호출 할 때마다 계산할 수있다, 믿는다.

+2

배열의 경우 아니요, 아니요. 배열의 경우 'Count'는 단순히 'Length' 속성을 호출합니다. –

+0

사실 그것은'ICollection'을 구현 한 모든 콜렉션에 대해'ICollection.Count'를 리턴합니다. 배열에서이 속성은 암시 적으로 구현됩니다. 따라서 배열에 직접 액세스 할 때이를 볼 수 없습니다. 'ICollection.Count'는 배열의'Length' 속성을 리턴합니다. –