루프가 반대로 더 빠릅니까?


268

나는 이것을 꽤 많이 들었다. 역으로 계산할 때 JavaScript 루프가 실제로 더 빠릅니까? 그렇다면 왜 그렇습니까? 역 루프가 빠르다는 것을 보여주는 몇 가지 테스트 스위트 예제를 보았지만 그 이유에 대한 설명을 찾을 수 없습니다!

루프가 더 이상 완료되었는지 확인하고 최종 숫자 값과 비교하여 확인할 때마다 더 이상 속성을 평가할 필요가 없기 때문에 가정합니다.

for (var i = count - 1; i >= 0; i--)
{
  // count is only evaluated once and then the comparison is always on 0.
}

6
hehe. 그것은 무한정 걸릴 것입니다. i를 시도해보십시오
StampedeXV

5
for상한 (hehe, 하한) 루프 제어 변수를 객체에서 정의하거나 가져올 필요가 없기 때문에 역방향 루프가 더 빠릅니다. 상수 0입니다.
Josh Stodola

88
실제 차이없습니다 . 네이티브 루프 구문은 항상 매우 빠릅니다 . 그들의 성능에 대해 걱정하지 마십시오.
James Allardice

24
@Afshin : 이와 같은 질문이있는 경우 참조 하는 기사를 알려 주십시오 .
궤도에서 가벼움 경주

22
초저가 및 배터리 구동 장치에는 주로 차이가 있습니다. 차이점은 i의 경우 루프 끝에서 0과 비교하고 i ++의 경우 숫자> 0과 비교한다는 것입니다. 성능 차이는 20 나노초와 비슷합니다 (cmp ax, 0 vs. cmp ax와 같은 것) , bx)-이것은 초당 수천 번 반복한다면 각각 20 나노초의 이득을 얻지 못하는 이유는 무엇입니까? :)
luben

답변:


902

그것 i--보다 빠르지는 않습니다 i++. 사실, 둘 다 똑같이 빠릅니다.

오름차순 루프에서 시간이 걸리는 것은 각각 i의 배열 크기를 평가 하는 것입니다. 이 루프에서 :

for(var i = array.length; i--;)

이 루프의 .length경우 선언 할 때 한 번만 평가 합니다.i

for(var i = 1; i <= array.length; i++)

검사 할 때 .length마다 증분 i할 때 마다 평가 합니다 i <= array.length.

대부분의 경우 이러한 종류의 최적화에 대해 걱정하지 않아도 됩니다.


23
array.length에 변수를 도입하고 for 루프의 헤드에 사용하는 것이 가치가 있습니까?
ragatskynet

39
@ragatskynet : 아니요. 벤치 마크를 설정하지 않고 지적하고 싶지 않은 한.
Jon

29
@ragatskynet 그것은 의존합니다 : .length특정 횟수만큼 평가 하거나 새로운 변수를 선언하고 정의하는 것이 더 빠릅 니까? length평가하는 데 비용이 많이 들지 않는 한 대부분의 경우 이는 조기 최적화 입니다.
alestanis

10
@ Dr.Dredel : 그것은 비교가 아닙니다-그것은 평가입니다. 0보다 평가하는 것이 더 빠릅니다 array.length. 아마.
궤도에서 가벼움 경주

22
언급 할 가치가있는 것은 Ruby, Python과 같은 해석 된 언어에 대해 이야기하고 있다는 것입니다. 컴파일 된 언어, 예를 들어 Java는 컴파일러 수준에서 최적화되어 있으며 이러한 차이 .length는 선언 여부 에 관계없이 이러한 차이를 "부드럽게"합니다 for loop.
Haris Krajina

198

이 사람 은 많은 브라우저에서 자바 스크립트의 많은 루프를 비교했습니다. 그는 또한 테스트 스위트를 가지고 있으므로 직접 실행할 수 있습니다.

모든 경우에 (내 읽기에서 하나를 놓치지 않는 한) 가장 빠른 루프는 다음과 같습니다.

var i = arr.length; //or 10
while(i--)
{
  //...
}

Nice :) 그러나 뒤로 "for"-loop 테스트는 없습니다 ... 그러나 peirix 또는 searlea가 언급 한 for 루프는 "i--"를 조건으로하는 "while"루프와 거의 동일해야합니다. 그리고 그것은 가장 빠른 루프 테스트였습니다.
SvenFinke

11
흥미롭지 만 사전 감소가 더 빠를 지 궁금합니다. i의 중간 값을 저장할 필요가 없기 때문에.
tvanfosson

내가 올바르게 기억한다면, 하드웨어 과정 전문가는 0에 대한 테스트가 0이 아닌 가장 빠른 "계산"이라고 말했다. while (i--)에서 테스트는 항상 0에 대한 테스트입니다. 아마도 이것이 가장 빠른 이유일까요?
StampedeXV

3
@tvanfosson 만약 당신이 사전 감소 --i한다면 당신은 var current = arr[i-1];루프 내부에서 사용해야 하거나 하나에 의해 해제됩니다 ...
DaveAlger

2
나는 두 번째 경우에 프로세서가 감소하고 새로운 값에 대해 테스트해야하기 때문에 (i 명령어 사이에 데이터 의존성이 있음) i는 i보다 빠를 수 있다고 들었습니다. 첫 번째 경우에는 프로세서가 기존 값을 테스트하고 나중에 값을 줄입니다. 이것이 JavaScript 또는 매우 낮은 수준의 C 코드에만 적용되는지 확실하지 않습니다.
marcus

128

나는이 답변으로 넓은 그림을 제시하려고합니다.

최근에 문제를 테스트 할 때까지 괄호 안에 다음과 같은 생각이 있었습니다 .

[[ C / C ++ 와 같은 저수준 언어의 관점에서 , 변수가 0이거나 0이 아닌 경우 프로세서가 특수한 조건부 점프 명령을 갖도록 코드가 컴파일됩니다. 또한 이처럼 많은 최적화 가 필요한 경우 단일 프로세서 명령이 아니라을 의미 하기 때문에 대신 대신 갈 수 있습니다.]]
++ii++++ii++j=i+1, i=j

롤을 풀면 정말 빠른 루프를 수행 할 수 있습니다.

for(i=800000;i>0;--i)
    do_it(i);

보다 느려질 수 있습니다

for(i=800000;i>0;i-=8)
{
    do_it(i); do_it(i-1); do_it(i-2); ... do_it(i-7);
}

그러나 그 이유는 상당히 복잡 할 수 있습니다 (단, 게임에서 프로세서 명령 사전 처리 및 캐시 처리 문제가 있음).

요청한 JavaScript 와 같은 고급 언어의 관점 에서 라이브러리를 사용하는 경우 루프를위한 내장 함수를 최적화 할 수 있습니다. 최선의 방법을 결정하게하십시오.

결과적으로 JavaScript에서는 다음과 같은 것을 사용하는 것이 좋습니다.

array.forEach(function(i) {
    do_it(i);
});

또한 오류가 적으며 브라우저는 코드를 최적화 할 수 있습니다.

[비고 : 브라우저뿐만 아니라 쉽게 최적화 할 수있는 공간도 있습니다 forEach. 최신 브라우저를 사용하도록 기능 (브라우저에 따라 다름)을 재정의하기 만하면됩니다 ! :) @AMK 오히려 사용 가치가있다 특별한 경우라고 array.pop하거나 array.shift. 그렇게하면 커튼 뒤에 놓으십시오. 최대한 과잉은 에 옵션을 추가하는 것입니다 forEach루핑 알고리즘을 선택할 수 있습니다.]

또한 저수준 언어의 경우 가능하면 복잡한 루프 작업에 스마트 라이브러리 기능을 사용하는 것이 가장 좋습니다.

이러한 라이브러리는 또한 멀티 스레드 방식으로 작업을 수행 할 수 있으며 전문 프로그래머가 최신 상태로 유지할 수 있습니다.

좀 더 면밀히 조사했으며 C / C ++에서는 5e9 = (50,000x100,000) 연산의 경우에도 @alestanis와 같이 상수에 대해 테스트를 수행하면 위아래로 차이가 없다는 것을 알 수 있습니다. (JsPerf 결과는 때때로 일치하지 않지만 대체로 동일하게 말합니다. 큰 차이를 만들 수는 없습니다.)
따라서 --i"포쉬 한"것입니다. 더 나은 프로그래머처럼 보일뿐입니다. :)

다른 한편으로,이 5e9 상황에서 풀리려면 10 초가되면 12 초에서 2.5 초로, 20 초가되면 2.1 초로 줄었습니다. 최적화가 없었고 최적화로 인해 측정 할 수없는 작은 시간이되었습니다. :) (언 롤링은 위의 방식으로 또는를 사용하여 수행 할 수 i++있지만 JavaScript에서 앞으로 나아갈 수는 없습니다.)

모두 모두 : KEEP i--/ i++++i/ i++직업 인터뷰, 스틱에 차이가 array.forEach사용할 수 없거나 다른 복잡한 라이브러리 함수. ;)


18
핵심 단어는 "할 수있다"입니다. 풀린 루프도 원래 루프보다 느릴 수 있습니다. 최적화 할 때는 항상 변경 사항이 어떤 영향을 미쳤는지 정확히 측정하십시오.
jalf

1
@jalf 사실은 +1입니다. 서로 다른 언 루핑 길이 (> = 1)는 효율성이 다릅니다. 그렇기 때문에 가능한 경우이 작업을 라이브러리에 맡기는 것이 더 편리합니다. 브라우저가 다른 아키텍처에서 실행되므로 어떻게해야할지 결정하는 것이 더 좋습니다 array.each(...). 나는 그들이 루핑없는 평범한 for-loops를 시도하고 실험 할 것이라고 생각하지 않습니다.
Barney

1
@BarnabasSzabolcs이 질문은 특히 C 또는 다른 언어가 아닌 JavaScript에 대한 것입니다. JS 거기에 있다 차이, 내 대답은 아래를 참조하십시오. 질문에 해당되지 않지만 +1 좋은 답변입니다.
AMK

1
그리고 당신은 간다- +1당신에게 Great Answer배지 를 얻으려면 . 정말 좋은 대답입니다. :)
Rohit Jain

1
APL / A ++도 언어가 아닙니다. 사람들은이 언어를 사용하여 특정 언어에 관심이없고 그 언어가 공유하는 것에 관심이 있음을 표현합니다.
바니

33

i-- ~만큼 빠르다 i++

아래 코드는 귀하의 것보다 빠르지 만 추가 변수를 사용합니다.

var up = Things.length;
for (var i = 0; i < up; i++) {
    Things[i]
};

권장 사항은 매번 어레이의 크기를 평가하지 않는 것입니다. 큰 어레이의 경우 성능 저하를 볼 수 있습니다.


6
당신은 분명히 틀 렸습니다. 이제 루프 제어에는 추가 내부 변수 (i 이상)가 필요하며 JavaScript 엔진에 따라 코드 최적화 가능성이 제한 될 수 있습니다. JIT는 간단한 루프를 기계 opcode를 지시하도록 변환하지만 루프에 변수가 너무 많으면 JIT가 최적화 할 수 없습니다. 일반적으로 JIT가 사용하는 아키텍처 또는 CPU 레지스터에 의해 제한됩니다. 한 번 초기화하고 단순히 가장 깨끗한 솔루션을 사용하면 모든 곳에서 권장됩니다.
Pavel P

추가 변수는 공통 인터프리터 / 컴파일러의 최적화 프로그램에 의해 제거됩니다. 요점은 '0과 비교'입니다. 자세한 설명은 내 대답을 참조하십시오.
H.-Dirk Schmitt

1
루프 안에 '위'를 넣는 것이 for (var i=0, up=Things.length; i<up; i++) {}
좋습니다

22

주제에 관심이 있으니 JavaScript 루프 벤치 마크인 JavaScript에서 루프를 코딩 하는 가장 빠른 방법은 무엇입니까 에 대한 Greg Reimer의 웹 로그 게시물을 살펴보십시오 . :

JavaScript에서 루프를 코딩하는 다양한 방법을위한 루프 벤치마킹 테스트 스위트를 구축했습니다. 이미 몇 가지가 있지만 네이티브 배열과 HTML 컬렉션의 차이점을 인정하는 것을 찾지 못했습니다.

또한 열어서 루프에서 성능 테스트를 수행 할 수 있습니다 https://blogs.oracle.com/greimer/resource/loop-test.html(예 : NoScript 등으로 브라우저에서 JavaScript가 차단 된 경우 작동하지 않음 ).

편집하다:

밀라노 Adamovsky에 의해 생성 된 최근의 벤치 마크 실행시에 수행 할 수 있습니다 여기에 다른 브라우저.

A의 맥 OS X에서 파이어 폭스 17.0에서 테스트 10.6 나는 다음과 같은 루프를 가지고 :

var i, result = 0;
for (i = steps - 1; i; i--) {
  result += i;
}

가장 빠른 선행 :

var result = 0;
for (var i = steps - 1; i >= 0; i--) {
  result += i;
}

벤치 마크 예.


5
그 지위는 4 살입니다. JavaScript 엔진이 업데이트 된 속도 (ha!)를 감안할 때 대부분의 조언은 더 이상 사용되지 않을 수 있습니다.이 기사에서는 Chrome을 언급하지 않고 반짝이는 V8 JavaScript 엔진입니다.
Yi Jiang

네, 지적 해 주셔서 감사합니다. 당시의 이벤트는 루프에서 --i 또는 i ++ 사이에 큰 차이가 없었습니다.
dreamcrash

19

--또는 아닌 ++, 비교 작업입니다. 를 사용 --하면 0과 비교를 사용할 수 있지만 ++길이와 비교해야합니다. 프로세서에서 0과 비교는 일반적으로 사용 가능하지만 유한 정수와 비교하려면 빼기가 필요합니다.

a++ < length

실제로 다음과 같이 컴파일됩니다

a++
test (a-length)

따라서 컴파일 할 때 프로세서에서 시간이 더 걸립니다.


15

짧은 답변

일반 코드, 특히 JavaScript 와 같은 고급 언어의 경우 i++및에 성능 차이가 없습니다 i--.

성능 기준은 for루프 및 비교 에서의 사용입니다. 문.

이것은 모든 고급 언어에 적용되며 대부분 JavaScript 사용과 무관합니다. 결론은 최종 결과 어셈블러 코드입니다.

상해

루프에서 성능 차이가 발생할 수 있습니다. 배경은에 있다는 것입니다 어셈블러 코드 수준 당신이이 것을 볼 수 있습니다 compare with 0추가 등록이 필요하지 않습니다 하나의 문입니다.

이 비교는 루프의 모든 패스에서 발행되며 성능이 크게 향상 될 수 있습니다.

for(var i = array.length; i--; )

다음 과 같은 의사 코드 로 평가됩니다 .

 i=array.length
 :LOOP_START
 decrement i
 if [ i = 0 ] goto :LOOP_END
 ... BODY_CODE
 :LOOP_END

참고 0 리터, 바꾸어 말하면, 일정한 값이된다.

for(var i = 0 ; i < array.length; i++ )

다음 과 같은 의사 코드 로 평가됩니다 (일반 인터프리터 최적화 가정).

 end=array.length
 i=0
 :LOOP_START
 if [ i < end ] goto :LOOP_END
 increment i
 ... BODY_CODE
 :LOOP_END

참고 단부 필요한 변수 CPU의 레지스터. 이는 코드에서 추가 레지스터 스와핑 을 호출 할 수 있으며 명령문 에서 더 비싼 비교문이 필요합니다 if.

내 5 센트 만

고급 언어의 경우 약간의 성능 향상으로 유지 관리가 용이 ​​한 가독성이 더 중요합니다.

일반적으로 배열 시작부터 끝까지 고전적인 반복 이 더 좋습니다.

배열 끝에서 시작하여 반복이 빠를 수록 원하지 않는 반전 순서가 발생할 수 있습니다.

포스트 스크립트

의견에서 묻는 것처럼 : 감소 전후 의 차이점 --ii--평가에 i있습니다.

가장 좋은 설명은 시도해 보는 것입니다. ;-) 여기 Bash 예제가 있습니다.

 % i=10; echo "$((--i)) --> $i"
 9 --> 9
 % i=10; echo "$((i--)) --> $i"
 10 --> 9

1
1+ 좋은 설명. 그냥 질문 범위의 작은 밖으로, 당신은 차이를 설명하십시오 수 --ii--도를?
Afshin Mehrabani

14

Sublime Text 2에서 동일한 권장 사항을 보았습니다.

이미 언급했듯이 주요 개선 사항은 for 루프의 각 반복에서 배열의 길이를 평가하지 않는 것입니다. 이것은 잘 알려진 최적화 기술이며 배열이 HTML 문서의 일부일 때 ( for모든 li요소에 대해 a) JavaScript에서 특히 효율적입니다 .

예를 들어

for (var i = 0; i < document.getElementsByTagName('li').length; i++)

보다 느리다

for (var i = 0, len = document.getElementsByTagName('li').length; i < len; i++)

내가 서있는 곳에서 귀하의 질문에있는 양식의 주요 개선 사항은 추가 변수를 선언하지 않는다는 사실입니다 ( len제 예에서는)

그러나 나에게 묻는다면 요점은 i++vs i--최적화가 아니라 각 반복에서 배열의 길이를 평가할 필요가 없다는 것입니다 ( jsperf 에서 벤치 마크 테스트를 볼 수 있음 ).


1
여기서 계산 하는 단어를 제외해야합니다 . Pavel의 답변에 대한 내 의견을 참조하십시오 . ECMA 사양에 따르면 배열 길이는 참조 할 때 계산되지 않습니다.
kojiro

'평가'가 더 나은 선택입니까? 흥미로운 사실 ​​btw, 나는 몰랐다
BBog

추가 변수는 공통 인터프리터 / 컴파일러의 옵티 마이저에 의해 제거됩니다. array.length 평가에도 동일하게 적용됩니다. 요점은 '0과 비교'입니다. 자세한 설명은 내 대답을 참조하십시오.
H.-Dirk Schmitt

@ H.-DirkS 당신의 상식적인 답변을 제쳐두고, JavaScript 역사상 오랫동안 컴파일러는 조회 체인의 성능 비용을 최적화 하지 않았습니다 . AFAIK V8이 가장 먼저 시도되었습니다.
kojiro

kojiro가 말한 것처럼 @ H.-DirkSchmitt는 잘 알려져 있고 잘 알려진 트릭입니다. 최신 브라우저에서는 더 이상 관련이 없어도 여전히 사용되지 않습니다. 또한 길이에 대한 새로운 변수를 도입하거나 OP의 질문에 대한 트릭을 사용하여 수행하는 것이 여전히 최선의 방법입니다. 그것은 현명한 일이며 좋은 습관입니다. 컴파일러가 JS에서 나쁜 일을 자주 처리하도록 최적화되었다는 사실과 관련이 없다고 생각합니다.
BBog

13

JavaScript i--보다 빠르다고 말하는 것이 합리적이라고 생각하지 않습니다 i++.

우선 , 그것은 JavaScript 엔진 구현에 전적으로 달려 있습니다.

둘째로 , 가장 간단한 구성이 JIT되고 기본 명령으로 변환되면 i++vs i--는 명령 을 실행하는 CPU에 전적으로 의존합니다. 즉, ARM (휴대폰)에서는 단일 명령으로 감소 및 0을 비교하기 때문에 0으로 내려가는 것이 더 빠릅니다.

아마, 당신은 제안 된 방법이 있기 때문에 하나가 다른 것보다 낭비되었다고 생각했습니다.

for(var i = array.length; i--; )

그러나 제안 된 방법은 하나가 다른 것보다 빠르기 때문에가 아니라 단순히

for(var i = 0; i < array.length; i++)

그런 다음 모든 반복에서 array.length평가해야했습니다 (더 똑똑한 JavaScript 엔진은 루프가 배열의 길이를 변경하지 않을 수도 있음을 알 수 있습니다). 간단한 문장처럼 보이지만 실제로는 JavaScript 엔진에 의해 호출되는 함수입니다.

또 다른 이유 i--는 "빠른"것으로 간주 될 수있는 이유 는 JavaScript 엔진이 루프를 제어하기 위해 내부 변수를 하나만 할당해야하기 때문입니다 (의 변수 var i). array.length 또는 다른 변수와 비교할 경우 루프를 제어하기 위해 둘 이상의 내부 변수가 있어야하고 내부 변수의 수는 JavaScript 엔진의 자산으로 제한됩니다. 루프에서 사용되는 변수가 적을수록 JIT가 최적화 할 가능성이 높아집니다. 그래서 i--더 빠르게 고려할 수 있습니다 ...


3
array.length평가 방법 에 대해 신중하게 표현할 가치가 있습니다. 길이는 참조 할 때 계산 되지 않습니다 . 배열 인덱스를 만들거나 변경할 때마다 설정되는 속성 일뿐 입니다. 추가 비용이 발생하면 JS 엔진이 해당 이름에 대한 조회 체인을 최적화하지 않았기 때문입니다.
kojiro

글쎄, Ecma 사양이 무엇인지 확실하지 않지만 다른 JavaScript 엔진의 내부에 대해 아는 getLength(){return m_length; }것은 하우스 키핑이 관련되어 있기 때문에 간단하지 않습니다 . 그러나 뒤로 생각하려고하면 길이를 실제로 계산 해야하는 배열 구현을 작성하는 것이 매우 독창적입니다 :)
Pavel P

ECMA 사양 에서는 길이 속성이 이미 계산되어 있어야 합니다. 는 lengthA-인 속성 즉-AN-배열 인덱스에 추가되거나 변경 될 때마다 즉시 업데이트되어야한다.
코지로

내가 말하려고하는 것은 사양에 대해 생각하면 사양을 위반하는 것이 매우 어렵다는 것입니다.
Pavel P

1
x86은 그런 점에서 ARM과 같습니다. dec/jnzinc eax / cmp eax, edx / jne.
Peter Cordes

13

다른 답변은 귀하의 특정 질문에 답변하지 않는 것 같습니다 (그중 절반 이상이 C 예제를 보여주고 하위 언어를 논의하므로 귀하의 질문은 JavaScript에 대한 것입니다).

그래서 여기 있습니다 :

간단한 대답 : i-- 일반적으로 실행될 때마다 0을 비교할 필요가 없으므로 일반적으로 더 빠릅니다. 다양한 방법에 대한 테스트 결과는 다음과 같습니다.

시험 결과: jsPerf에서 "증명 된" arr.pop()것은 실제로 가장 빠른 루프입니다. 그러나, 초점에 --i, i--, i++++i 요약 된 결과를 귀하의 질문에 질문으로, 여기 (그들은 아래의 소스를 참조하십시오 여러 jsPerf의 출신) jsPerf입니다 :

--i그리고 i--동안 파이어 폭스에서 동일한 i--빠른 크롬입니다.

크롬 (루프의 기본에 for (var i = 0; i < arr.length; i++)) 빨리보다 i----i파이어 폭스에서 느린있는 동안.

Chrome과 Firefox에서 캐시 arr.length를 사용하면 Chrome이 약 170,000 ops / sec 앞당겨집니다.

큰 차이가 없으면 대부분의 브라우저 ++i보다 빠릅니다 i++. AFAIK는 다른 브라우저에서 결코 다른 방법이 아닙니다.

더 짧은 요약 : arr.pop() 지금까지 가장 빠른 루프입니다. 구체적으로 언급 된 루프의 i--경우 가장 빠른 루프입니다.

출처 : http://jsperf.com/fastest-array-loops-in-javascript/15 , http://jsperf.com/ipp-vs-ppi-2

이것이 귀하의 질문에 답변되기를 바랍니다.


1
당신의 것 같습니다 pop까지 내가 말할 수있는 - 그것은 루프의 대부분 0으로 배열의 크기 아래로 감소하기 때문에 테스트는 꽤 빠른 것 같다. 보여줄 것 - 그러나 반드시 일을 나는 각각의 테스트와 같은 방법으로 배열을 만들려면이 jsperf 설계 한 공평하게 .shift()내 몇 브라우저의 승자로서을 - 나는 :)하지만 예상했을 것없는 것 jsperf.com / Compare의 다른 유형의 루핑
Pebbl

언급하는 유일한 사람이기 위해 Upvoted ++iD :
jaggedsoft

12

메모리에 어레이를 배치하고 해당 어레이에 액세스하는 동안 메모리 페이지의 적중률에 따라 다릅니다.

경우에 따라 적중률의 증가로 인해 열 순서로 배열 멤버에 액세스하는 것이 행 순서보다 빠릅니다.


1
OP가 오직 다른 순서로 동일한 행렬을 순회하는 데 다른 시간이 걸릴 수있는 이유를 물었다면
dcow

1
운영 체제에서 메모리 관리가 페이징을 기반으로한다는 점을 고려하면 프로세스가 캐시 된 페이지에없는 데이터가 필요할 때 OS에서 페이지 오류가 발생하고 대상 페이지를 CPU 캐시로 가져 와서 다른 페이지로 바꿔야합니다. 대상 페이지가 CPU 캐시에있을 때보 다 처리 시간이 오래 걸립니다. 각 행이 페이지 OS 크기보다 큰 대형 배열을 정의하고 행 순서로 액세스한다고 가정하십시오.이 경우 페이지 결함 비율이 증가하고 결과는 해당 배열에 대한 열 순서 액세스보다 느립니다.
Akbar Bayati

페이지 결함은 캐시 누락과 다릅니다. 메모리가 디스크로 페이징 된 경우에만 페이지 결함이 발생합니다. 메모리에 저장되는 방식에 따라 순차적으로 다차원 배열에 액세스하는 것은 페이지 결함이 아니라 캐시 위치 (페치 라인의 모든 바이트 사용)로 인해 더 빠릅니다. (작업 세트가 사용중인 컴퓨터에 비해 너무 크지 않은 경우)
Peter Cordes

10

6502 어셈블리 (8 비트, 예!)를 작성할 때 마지막으로 신경 쓰지 않았습니다 . 가장 큰 이득은 대부분의 산술 연산 (특히 감소)이 플래그 세트를 업데이트한다는 것입니다.Z 는 '도달 된 0'지표입니다.

따라서 루프가 끝나면 DEC(감소)와 JNZ(0이 아닌 경우 점프 ) 두 가지 명령을 수행했습니다. 비교가 필요하지 않습니다!


JavaScript의 경우 분명히 적용되지 않습니다 (이러한 op 코드가없는 CPU에서 실행되므로). i--vs의 배후에있는 진짜 이유는 아마도 i++전자의 경우 루프 범위에서 추가 제어 변수를 도입하지 않기 때문입니다. 아래 내 답변을 참조하십시오 ...
Pavel P

1
맞습니다, 그것은 실제로 적용되지 않습니다; 그러나 그것은 매우 일반적인 C 스타일이며, 우리에게 익숙한 사람들에게는 더 깨끗해 보입니다. :-)
Javier

x86과 ARM은 모두이면에서 6502와 같습니다. x86 케이스 dec/jnz대신 inc/cmp/jne. 빈 루프가 더 빨리 실행되는 것을 볼 수는 없지만 (두 가지 모두 처리량을 포화시킬 수 있음) 카운트 다운하면 루프 오버 헤드가 약간 줄어 듭니다. 현재 인텔 HW 프리 페처는 내림차순으로 메모리 액세스 패턴에 의해 방해받지 않습니다. 구형 CPU 나는 4 개의 역방향 스트림과 6 또는 10 개의 전방 스트림, IIRC를 추적 할 수 있다고 생각합니다.
Peter Cordes

7

JavaScript (및 모든 언어)가 결국 CPU에서 실행되도록 opcode로 바뀌는 것으로 설명 할 수 있습니다. CPU는 항상 0과 비교하기위한 단일 명령을 가지고 있으며, 이는 매우 빠릅니다.

따로, countis is always를 보장 할 수 있으면 다음과 같이 >= 0단순화 할 수 있습니다.

for (var i = count; i--;)
{
  // whatever
}

1
소스 코드가 짧다고해서 반드시 빨라지는 것은 아닙니다. 당신은 그것을 측정 했습니까?
Greg Hewgill

죄송합니다. 머리에 못을 박으십시오.
Robert

1
0과 비교하는 것이 다른 어셈블리 소스를보고 싶습니다. 몇 년이 지났지 만 한 번에 수많은 어셈블리 코딩을 수행했으며 인생에서 똑같이 빠를 수없는 방식으로 0에 대해 비교 / 테스트를 수행하는 방법을 생각할 수 없었습니다. 다른 정수 그러나 당신이 말하는 것은 사실입니다. 왜 그런지 알지 못해서 좌절했습니다!
Brian Knoblauch

7
@Brian Knoblauch : "dec eax"(x86 코드)와 같은 명령어를 사용하는 경우 해당 명령어는 자동으로 Z (제로) 플래그를 설정하며 그 사이에 다른 비교 명령어를 사용하지 않고도 즉시 테스트 할 수 있습니다.
Greg Hewgill

1
Javascript를 해석 할 때 opcode가 병목 현상이 될지 의심됩니다. 토큰 수가 적을수록 통역사가 소스 코드를 더 빠르게 처리 할 수 ​​있습니다.
Todd Owen

6

이것은 --또는++ 부호 않지만 루프에서 적용하는 조건에 따라 다릅니다.

예를 들어, 루프 길이가 배열의 길이나 다른 조건과 같이 매번 조건을 확인하는 것보다 변수에 정적 값이 있으면 루프가 더 빠릅니다.

그러나 이번 최적화는 나노초 단위로 측정되므로이 최적화에 대해 걱정하지 마십시오.


여러 나노초 루프가 초가 될 수 있습니다 ... 시간이있을 때 최적화하는 것은 결코 나쁜 생각이 아닙니다.
Buksy

6

for(var i = array.length; i--; )훨씬 빠르지 않습니다. 바꿀 때 array.lengthsuper_puper_function(), 그것은있을 수 있습니다 크게 (이 모든 반복에서라고 때문에) 더 빨리. 그 차이입니다.

2014 년에 변경하려는 경우 최적화에 대해 생각할 필요가 없습니다. "검색 및 바꾸기"로 변경하려는 경우 최적화에 대해 생각할 필요가 없습니다. 시간이 없다면 최적화에 대해 생각할 필요가 없습니다. 그러나 지금, 당신은 그것에 대해 생각할 시간이 있습니다.

PS : i--보다 빠르지 않습니다 i++.


6

간단히 말하면 : JavaScript 에서이 작업을 수행하는 데 아무런 차이가 없습니다.

우선, 직접 테스트 할 수 있습니다.

JavaScript 라이브러리에서 스크립트를 테스트하고 실행할 수있을뿐만 아니라 이전에 작성된 모든 스크립트에 액세스 할 수있을뿐만 아니라 다른 플랫폼의 다른 브라우저에서 실행 시간의 차이를 확인할 수 있습니다.

지금까지 알 수 있듯이 모든 환경에서 성능에는 차이가 없습니다.

스크립트 성능을 향상 시키려면 다음을 수행하십시오.

  1. 가지고 var a = array.length;당신이 루프에서 값마다 계산되지 않도록 문을
  2. 루프 풀기 http://en.wikipedia.org/wiki/Loop_unwinding

그러나 얻을 수있는 개선은 그다지 중요하지 않으므로 대부분 신경 쓰지 않아도된다는 것을 이해해야합니다.

왜 그런 오해 (Dec vs Inc)가 나타 났는지에 대한 내 의견

오래 전, 일반적인 기계 명령어 인 DSZ (Decrement and Skip on Zero)가있었습니다. 어셈블리 언어로 프로그래밍 한 사람들은 레지스터를 저장하기 위해이 명령어를 사용하여 루프를 구현했습니다. 이제이 고대 사실은 더 이상 사용되지 않으며이 의사 개선을 사용하여 어떤 언어로도 성능 향상을 얻지 못할 것이라고 확신합니다.

우리 시대에 그러한 지식이 전파 될 수있는 유일한 방법은 다른 사람의 사람 코드를 읽는 것입니다. 이러한 구성을보고 구현 된 이유와 여기에 "제로에 비해 성능이 향상됩니다"라는 대답이 표시됩니다. 당신은 당신의 동료에 대한 더 높은 지식에 당황하게되었고 훨씬 똑똑하게 사용하려고 생각합니다 :-)


흥미롭지 만 win7의 firefox 16.0.2에서 실행되는 테스트의 경우 감소 루프가 29 % 느려졌습니다 ... 편집 : 무시하십시오. 반복 된 테스트가 결정적이지 않은 것으로 판명되었으며, 후속 실행에 대한 테스트 결과에 놀라 울 정도의 노이즈가 있습니다. 왜 그런지 잘 모르겠습니다.

그래, 나는 다른 모든 것을 닫고 테스트를 실행함으로써 그것을 설명하려고 노력했다. 여전히 놀라운 결과를 얻었습니다. 아주 이상한.

제로가는 것이 JavaScript에서 더 나은 것으로 간주되는 실제 요점을 놓친 것 같습니다. 주로 이런 식으로 하나의 변수 만 루프 실행을 제어하기 때문입니다. 예를 들어 옵티 마이저 / JITer는 개선 할 여지가 더 많습니다. array.lengthJS 가상 머신이 루프의 본문에 의해 배열이 수정되지 않았는지 알아낼 수있을 정도로 똑똑하기 때문에 사용으로 인해 성능이 저하되는 것은 아닙니다. 아래 답변을 참조하십시오.
Pavel P

1
nitpicking :이 고대 사실 (어셈블리 언어 최적화)은 더 이상 사용 되지 않으며, 단지 비전입니다. 당신이 정말로하지 않으면 알 필요가 없습니다. :-)
Javier

6

내가 만든 jsbench에 비교 .

알레스 타니가 지적했듯이, 오름차순 루프에서 시간이 걸리는 한 가지 것은 각 반복마다 배열의 크기를 평가하는 것입니다. 이 루프에서 :

for ( var i = 1; i <= array.length; i++ )

.length증분 할 때마다 평가 합니다 i. 이것에서 :

for ( var i = 1, l = array.length; i <= l; i++ )

.length선언 할 때 한 번만 평가 합니다 i. 이것에서 :

for ( var i = array.length; i--; )

비교는 암시 적이며 감소하기 직전에 발생 i하며 코드는 매우 읽을 수 있습니다. 그러나 큰 차이를 만들 수있는 것은 루프 안에 넣는 것입니다.

함수 호출과 함께 루프 (다른 곳에 정의 됨) :

for (i = values.length; i-- ;) {
  add( values[i] );
}

인라인 코드로 루프 :

var sum = 0;
for ( i = values.length; i-- ;) {
  sum += values[i];
}

가독성을 떨어 뜨리지 않고 함수를 호출하는 대신 코드를 인라인 할 수 있다면 루프를 10 배 빠르게 처리 할 수 ​​있습니다!


참고 : 브라우저가 간단한 함수 를 인라인하는 데 능숙 해짐에 따라 코드의 복잡도에 따라 달라집니다. 따라서 최적화하기 전에 프로필을 작성하십시오.

  1. 병목 현상이 다른 곳 (아약스, 리플 로우 등) 일 수 있습니다.
  2. 더 나은 알고리즘을 선택할 수 있습니다
  3. 더 나은 데이터 구조를 선택할 수 있습니다

하지만 기억해:

사람들이 읽을 수 있도록 기계가 실행되도록 코드가 작성됩니다.


이 답변과 벤치 마크에 +1. forEach 테스트를 추가하고 브라우저 및 노드에서 실행할 수있는 독립 실행 형 파일에 대한 벤치 마크를 재 작업했습니다. jsfiddle.net/hta69may/2 . 노드의 경우 "역 루프, 암시 적 비교, 인라인 코드"가 가장 빠릅니다. 그러나 FF 50에서의 테스트는 호기심 많은 결과를 보여주었습니다. 타이밍은 거의 10 배 (!) 낮았을뿐만 아니라 두 "forEach"테스트 모두 "리버스 루프"만큼 빠릅니다. 아마도 노드 녀석은 V8 대신 Mozilla의 JS 엔진을 사용해야합니까? :)
Fr0sT

4

당신이 지금하고있는 방식은 더 빠르지 않습니다 (무한한 루프를 제외하고는, 당신이해야 할 것으로 생각합니다 i--.

더 빨리 만들고 싶다면 :

for (i = 10; i--;) {
    //super fast loop
}

물론 작은 루프에서는 눈치 채지 못할 것입니다. 더 빠른 이유는 "true"인지 확인하면서 i를 감소시키기 때문입니다 (0에 도달하면 "false"로 평가됨).


1
세미콜론이 없습니까? (i = 10; i--;)
searlea

예, 실수를 고쳤습니다. 그리고 만약 우리가 까다로울 거라면 당신의 i 이후에 당신의 세미콜론을 잊어 버렸습니다! 허.
djdd87

왜 더 빠를까요? 소스가 짧다고해서 더 빠를 수는 없습니다. 당신은 그것을 측정 했습니까?
Greg Hewgill

4
예, 나는 그것을 측정했으며, 더 짧은 소스가 더 빠르다고 말하지는 않지만 더 적은 작업으로 더 빠릅니다.
peirix

4

코드를 작성하는 방식을 약간만 변경하면 코드가 실제로 얼마나 빨리 실행되는지 크게 달라질 수 있습니다. 사소한 코드 변경으로 인해 실행 시간이 크게 달라질 수있는 영역은 배열을 처리하는 for 루프가있는 것입니다. 배열이 웹 페이지의 요소 (예 : 라디오 버튼) 인 경우 변경이 가장 큰 영향을 주지만 배열이 Javascript 코드 내부에있는 경우에도이 변경 사항을 적용 할 가치가 있습니다.

배열을 처리하기 위해 for 루프를 코딩하는 일반적인 방법은 다음과 같습니다.

for (var i = 0; i < myArray.length; i++) {...

이것에 대한 문제는 myArray.length를 사용하여 배열의 길이를 평가하는 데 시간이 걸리고 루프를 코딩 한 방식은 루프마다 매번이 평가를 수행해야한다는 것을 의미합니다. 배열에 1000 개의 요소가 포함 된 경우 배열의 길이는 1001 배로 평가됩니다. 라디오 버튼을보고 있고 myForm.myButtons.length가있는 경우 루프에서 매번 길이를 평가하기 전에 지정된 양식 내의 적절한 버튼 그룹을 먼저 찾아야하므로 평가하는 데 시간이 더 오래 걸립니다.

분명히 배열을 처리하는 동안 배열의 길이가 변경되는 것을 기대하지 않으므로 길이의 이러한 모든 재 계산이 처리 시간에 불필요하게 추가됩니다. (물론 루프 내부에 배열 항목을 추가하거나 제거하는 코드가있는 경우 배열 크기는 반복 사이에서 변경 될 수 있으므로 테스트하는 코드를 변경할 수 없습니다)

크기가 고정 된 루프에 대해이 문제를 해결하려면 루프 시작시 길이를 한 번 평가하여 변수에 저장해야합니다. 그런 다음 루프를 종료 할 시점을 결정하기 위해 변수를 테스트 할 수 있습니다. 이는 특히 배열에 항목이 몇 개 이상 있거나 웹 페이지의 일부인 경우 배열 길이를 평가하는 것보다 훨씬 빠릅니다.

이를 수행하는 코드는 다음과 같습니다.

for (var i = 0, var j = myArray.length; i < j; i++) {...

이제 배열의 크기를 한 번만 평가하고 루프 주위에서 매번 해당 값을 보유하는 변수에 대해 루프 카운터를 테스트합니다. 이 추가 변수는 배열의 크기를 평가하는 것보다 훨씬 빠르게 액세스 할 수 있으므로 코드가 이전보다 훨씬 빠르게 실행됩니다. 스크립트에는 하나의 추가 변수 만 있습니다.

배열의 모든 항목이 처리되는 한 배열을 처리하는 순서는 중요하지 않습니다. 이 경우 방금 추가 한 추가 변수를 제거하고 배열을 역순으로 처리하여 코드를 약간 더 빠르게 만들 수 있습니다.

가장 효율적인 방법으로 배열을 처리하는 최종 코드는 다음과 같습니다.

for (var i = myArray.length-1; i > -1; i--) {...

이 코드는 여전히 시작시 한 번만 배열의 크기를 평가하지만 루프 카운터를 변수와 비교하는 대신 상수와 비교합니다. 상수는 변수보다 액세스하는 것이 훨씬 효과적이며 코드의 세 번째 버전보다 이전에 하나의 할당 문이 적기 때문에 두 번째 버전보다 약간 효율적이고 첫 번째 버전보다 훨씬 더 효율적입니다.


4

++대는 --자바 스크립트 인터프리터 언어가 아닌 컴파일 된 언어이기 때문에 문제가되지 않습니다. 각 명령어는 둘 이상의 기계 언어로 번역되므로 사용자는 세부 사항에 신경 쓰지 않아야합니다.

조립 지침을 효율적으로 사용하기 위해 --(또는 ++)를 사용하는 것에 대해 말하는 사람들 은 잘못되었습니다. 이 명령어는 정수 산술에 적용 되며 JavaScript에는 정수가 아니라 숫자 만 있습니다 .

읽을 수있는 코드를 작성해야합니다.


3

많은 경우에, 이것은 프로세서가 다른 비교보다 0과 빠르게 비교할 수 있다는 사실과 본질적으로 관련이 없습니다.

몇 가지 자바 스크립트 엔진 만 있기 때문입니다. (JIT를 목록에있는 사람)이 실제로 기계어 코드를 생성합니다.

대부분의 Javascript 엔진은 소스 코드의 내부 표현을 작성한 다음 해석합니다 (이것이 어떤 것인지 알기 위해 Firefox의 SpiderMonkey에서이 페이지 하단 부근을 살펴보십시오. ). 일반적으로 코드 조각이 실제로 동일한 기능을 수행하지만 내부 표현이 단순 해지면 더 빨리 실행됩니다.

변수에서 변수를 더하거나 빼는 것과 같은 간단한 작업이나 변수를 무언가와 비교하는 것과 같이, 하나의 내부 "명령"에서 다음으로 이동하는 인터프리터의 오버 헤드는 상당히 높으므로 "명령" JS 엔진에서 내부적으로 사용하면 좋습니다.


3

글쎄, 나는 JavaScript에 대해 모른다. 실제로 배열 길이를 재평가해야하고 연관 배열과 관련이 있어야한다 (감소하는 경우 새로운 항목을 할당하지 않을 것임) 배열은 밀도가 높습니다. 즉 누군가가 그것을 최적화 할 수 있습니다).

저수준 어셈블리에는 DJNZ (0이 아닌 경우 감소 및 점프)라는 루핑 명령어가 있습니다. 따라서 감소 및 점프는 모두 하나의 명령으로 이루어지며 INC 및 JL / JB보다 약간 빠릅니다 (증가, 아래의 경우 점프 / 미만이면 점프). 또한 0과 비교하는 것이 다른 숫자와 비교하는 것보다 간단합니다. 그러나 실제로는 거의 한계가 있으며 대상 아키텍처에 달려 있습니다 (예 : 스마트 폰의 팔에 차이를 만들 수 있음).

이 낮은 수준의 차이가 해석 된 언어에 큰 영향을 줄 것으로 기대하지는 않을 것입니다. 응답 중 DJNZ를 보지 못했기 때문에 흥미로운 생각을 공유 할 것이라고 생각했습니다.


기록 DJNZ은 8051 (z80) ISA의 지침입니다. x86 dec/jnz대신 inc/cmp/jne, 팔이 비슷한 것을 가지고 있습니다. 나는 이것이 자바 스크립트 차이의 원인이 아니라고 확신한다. 그것은 루프 조건에서 더 많은 평가를받는 것입니다.
Peter Cordes

3

그것은 사용 하나만 결과, 감소 된 값이 있기 때문에 (C ++에서) --i 빠른 것을 상기한다. i-- 감소 된 값을 다시 i로 저장하고 원래 값을 결과로 유지해야합니다 (j = i--;). 대부분의 컴파일러에서 이것은 하나의 레지스터가 아닌 두 개의 레지스터를 사용하여 레지스터 변수로 유지되지 않고 다른 변수를 메모리에 쓰도록 할 수 있습니다.

나는 요즘 차이가 없다고 말한 다른 사람들에게 동의합니다.


3

아주 간단한 말로

"i--와 i ++. 사실 둘 다 같은 시간이 걸립니다."

그러나이 경우 증분 연산이있는 경우. 프로세서는 변수가 1 씩 증가 할 때마다 .length를 평가하고 감소하는 경우 특히 .length가 0이 될 때까지 한 번만 평가합니다.


3

먼저, i++그리고 i--정확하게 자바 스크립트를 포함한 모든 프로그래밍 언어에서 동일한 시간이 걸릴.

다음 코드는 시간이 많이 걸립니다.

빠른:

for (var i = 0, len = Things.length - 1; i <= len; i++) { Things[i] };

느린:

for (var i = 0; i <= Things.length - 1; i++) { Things[i] };

따라서 다음 코드도 시간이 다릅니다.

빠른:

for (var i = Things.length - 1; i >= 0; i--) { Things[i] };

느린:

for (var i = 0; i <= Things.length - 1; i++) { Things[i] };

PS Slow 는 컴파일러 최적화로 인해 일부 언어 (JavaScript 엔진)에 대해서만 느립니다. 가장 좋은 방법은 '<'대신 '<=' (또는 '=') 및 '--i'대신 'i--'를 사용하는 것 입니다.


3

i 또는 i ++는 많은 시간을 소비하지 않습니다. 당신은 CPU 아키텍처 내부에 깊이 갈 경우는 ++댄 더 빠른이다 --때문에 --작업이 2의 보수를 할 것입니다,하지만 그것은 신속하고 사이에 큰 차이 만들 것입니다 그래서 하드웨어 내부에 무슨 일이 생긴 ++하고 --이러한 작업이로 간주됩니다 CPU에서 가장 적은 시간.

루프는 다음과 같이 실행합니다 :

  • 시작시 변수를 한 번 초기화하십시오.
  • 루프의 두 번째 피연산자에 제약 조건을 확인, <, >, <=, 등
  • 그런 다음 루프를 적용하십시오.
  • 루프를 증가시키고 루프는 다시 이러한 프로세스를 던집니다.

그래서,

for (var i = Things.length - 1; i >= 0; i--) {
    Things[i]
}; 

시작시 한 번만 배열 길이를 계산하며 많은 시간이 걸리지 않지만

for(var i = array.length; i--; ) 

각 루프에서 길이를 계산하므로 많은 시간이 소요됩니다.


var i = Things.length - 1; i >= 0; i--길이도 1 번 계산합니다.
Dmitry

1
나는 " --작업이 2의 보수를 할 것"이 무엇을 의미하는지 잘 모르겠지만 , 그것이 무언가를 부정 할 것이라고 생각합니다. 아니요, 어떤 아키텍처에서도 부정하지 않습니다. 1을 빼는 것은 1을 추가하는 것만 큼 간단합니다. 캐리가 아니라 빌리는 회로를 만들면됩니다.
Olathe

1

이런 종류의 질문에 대답하는 가장 좋은 방법은 실제로 시도하는 것입니다. 백만 번의 반복 횟수를 계산하는 루프를 설정하고 두 가지 방법으로 수행하십시오. 두 루프의 시간을 정하고 결과를 비교하십시오.

대답은 사용중인 브라우저에 따라 다를 수 있습니다. 일부는 다른 것과 다른 결과를 가질 것입니다.


4
그래도 더 빠른지 에 대한 그의 질문에 대답하지 않을 것입니다. 그는 왜 그런지에 대한 지식 없이도 벤치 마크를 얻었습니다.
peirix

3
사실입니다. 그러나 각 브라우저에서 각 Javascript 엔진의 정확한 구현을 알지 못하면 "왜"부분에 대답하는 것이 거의 불가능합니다. 여기에 많은 답변은 "후행 감소 대신 사전 퇴행 사용"(C ++ 최적화 트릭) 및 "0과 비교"와 같은 일화적인 권장 사항을 둘러싼 네이티브 코드 컴파일 언어에서는 사실이지만 Javascript는 CPU.
Greg Hewgill

4
-1 최선의 방법은 시도해 보는 것에 완전히 동의하지 않습니다. 몇 가지 예는 집단적 지식을 대체하지 않으며, 이것이 이와 같은 포럼의 요점입니다.
Christophe

1

그것을 사랑하지만, 마크가 많지만 대답이 없습니다 : D

단순히 0과 비교하면 항상 가장 빠른 비교입니다

따라서 (a == 0)은 (a == 5)보다 True를 반환 할 때 실제로 더 빠릅니다.

작고 중요하지 않으며 컬렉션에 1 억 개의 행이있어 측정 가능합니다.

즉, 루프 업하면 i <= array.length라고 말하고 i를 증가시킬 수 있습니다.

다운 루프에서 i> = 0이라고 말하고 대신 i를 줄입니다.

비교가 더 빠릅니다. 루프의 '방향'이 아닙니다.


Javascript 엔진이 모두 다르기 때문에 질문에 대한 답변이 없습니다. 답변은 측정하는 브라우저에 따라 다릅니다.
Greg Hewgill

아니요 기본적으로 0에 대한 비교가 가장 빠릅니다. 귀하의 진술은 정확하지만 0과 비교하는 황금률은 절대적입니다.
Robert

4
그건 사실입니다 컴파일러 선택한다면 확실히 보장되지 않으므로 그 최적화를 할 경우. 컴파일러는 상수 값을 제외하고 (a == 0) 및 (a == 5)에 대해 정확히 동일한 코드를 생성 할 수 있습니다. 비교의 양쪽이 모두 변수 인 경우 (CPU 관점에서) CPU는 다른 값보다 더 빨리 0과 비교하지 않습니다. 일반적으로 네이티브 코드 컴파일러 만이 수준에서 최적화 할 수 있습니다.
Greg Hewgill

1

다른 사람들은 HEADACHE를 피하십시오 --- 투표하십시오!

이 페이지에서 가장 인기있는 답변은 Firefox 14에서 작동하지 않으며 jsLinter를 통과하지 못합니다. "while"루프에는 할당이 아니라 비교 연산자가 필요합니다. 크롬, 사파리 및 심지어는 작동합니다. 그러나 파이어 폭스에서 사망합니다.

이건 부러졌어!

var i = arr.length; //or 10
while(i--)
{
  //...
}

이 작동합니다! (firefox에서 작동하고 jsLinter를 전달합니다)

var i = arr.length; //or 10
while(i>-1)
{
  //...
  i = i - 1;
}

2
방금 Firefox 14에서 시도했지만 정상적으로 작동했습니다. while (i--)많은 브라우저에서 사용 하고 작동 하는 프로덕션 라이브러리의 예제를 보았습니다 . 테스트에 이상한 점이 있었습니까? Firefox 14 베타 버전을 사용하고 있습니까?
매트 브라운

1

이것은 추측에 불과하지만 프로세서가 다른 값 (i <Things.length) 대신 0 (i> = 0)과 비교하는 것이 더 쉽기 때문일 수 있습니다.


3
+1 다른 사람들이 투표하지 않았습니다. .length의 반복 된 평가가 실제 증가 / 감소보다 훨씬 더 문제가되지만 루프 종료 점검이 중요 할 수 있습니다. 내 C 컴파일러는 "비고 # 1544-D : (ULP 13.1) 루프 카운트를 감지했습니다. 0을 감지하는 것이 더 쉬울
수록
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.