programing

루프가 정말 역방향으로 더 빠릅니까?

javaba 2022. 10. 27. 23:13
반응형

루프가 정말 역방향으로 더 빠릅니까?

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

루프가 완료되었는지 확인할 때마다 속성을 평가할 필요가 없어지고 최종 수치와 대조하여 확인할 수 있기 때문이라고 생각합니다.

예.

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

그게 아니라i--보다 빠르다i++사실 둘 다 똑같이 빨라요.

오름차순 루프에서 시간이 걸리는 것은 각각에 대한 평가입니다.i, 어레이의 크기.이 루프에서는:

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

평가하다.length단 한 번, 당신이 선언할 때i단, 이 루프에서는

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

평가하다.length증가할 때마다i확인했을 때i <= array.length.

대부분의 경우 이러한 최적화에 대해 걱정할 필요도 없습니다.

남자는 자바스크립트와 브라우저의 많은 루프를 비교했습니다.테스트 스위트도 있으니 직접 실행해 보세요.

모든 경우(읽기 중 하나를 빠뜨리지 않는 한) 가장 빠른 루프는 다음과 같습니다.

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

나는 이 대답으로 넓은 그림을 보여주려고 한다.

최근 이 문제를 테스트하기 전까지는 괄호 안의 다음 생각이 저의 신념이었습니다.

[C/C++와 같은 저수준 언어에서는 변수가 0(또는 0이 아닌 경우)일 때 프로세서가 특별한 조건부 점프 명령을 갖도록 코드가 컴파일됩니다.
또한 이 정도 최적화에 관심이 있다면++i대신i++,왜냐면++i1개의 프로세서명령어인데 반해i++수단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와 같이 라이브러리나 임베디드 기능에 의존하면 최적화 할 수 있습니다.그들이 그것을 어떻게 하는 것이 최선인지 결정하게 하세요.

따라서 자바스크립트에서는 다음과 같은 것을 사용하는 것이 좋습니다.

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

또, 에러 발생도 적고, 브라우저에서도 코드를 최적화할 수 있습니다.

[리마크: 브라우저뿐만 아니라 쉽게 최적화할 수 있는 공간도 확보되어 있습니다.forEach(브라우저에 의존하여) 최신 베스트 트릭을 사용하도록 기능합니다.@A.M.K.는 특별한 경우 사용할 가치가 있다고 말합니다.array.pop아니면array.shift그러면 커튼 뒤에 붙여주세요.가장 큰 오버킬은 옵션 추가입니다.forEach루핑 알고리즘을 선택합니다.]

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

이러한 라이브러리는, 멀티 스레드(멀티 스레드)에 대응해, 전문 프로그래머가 최신의 것을 유지할 수도 있습니다.

좀 더 자세히 살펴보니 C/C++에서는 5e9 = (50,000 x 100,000) 연산의 경우에도 @alestanis가 말하는 상수에 대해 테스트가 이루어지면 상승과 하강이 차이가 없다는 것을 알 수 있었습니다.(JSPerf의 결과가 일관되지 않을 수 있지만 대체로 같은 의견입니다. 큰 차이를 만들 수 없습니다.
그렇게--i'양심적인' 일이기도 해요그것은 당신을 더 나은 프로그래머처럼 보이게 할 뿐이다.:)

한편, 이 5e9 상황에서 등록하면, 10초 차이로 12초에서 2.5초로, 20초 차이로 2.1초로 감소했습니다.최적화를 실시하지 않았기 때문에, 최적화에 의해서, 측정할 수 없는 짧은 시간이 단축되었습니다. :) (위의 방법이나 사용하는 방법으로 롤링을 실시할 수 있습니다.i++그렇다고 자바스크립트에서는 앞서가는 것은 아닙니다.)

전체: 유지i--/i++그리고.++i/i++취업 면접과의 차이점, 고수array.forEach또는 기타 복잡한 라이브러리 기능을 사용할 수 있는 경우.;)

i--만큼 빠르다i++

다음 코드는 사용자의 코드만큼 빠르지만 추가 변수를 사용합니다.

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

매번 어레이 크기를 평가하지 않는 것이 좋습니다.대규모 어레이의 경우 성능 저하를 확인할 수 있습니다.

이 주제에 관심이 있으시다면 JavaScript 루프 벤치마크에 관한 Greg Remer의 웹로그 투고를 보시기 바랍니다.JavaScript에서 루프를 코드화하는 가장 빠른 방법은 무엇입니까?

JavaScript에서 루프를 코딩하는 다양한 방법을 위한 루프 벤치마킹 테스트 스위트를 만들었습니다.이미 몇 개 있지만 네이티브 어레이와 HTML 컬렉션의 차이를 인식할 수 있는 것을 찾을 수 없었습니다.

루프를 열어서 퍼포먼스 테스트를 실행할 도 있습니다.https://blogs.oracle.com/greimer/resource/loop-test.html(예를 들어 NoScript에 의해 브라우저에서 JavaScript가 차단되면 동작하지 않습니다).

편집:

Milan Adamovsky가 작성한 최신 벤치마크는 다른 브라우저의 런타임에 실행할 수 있습니다.

Mac OS X 10.6에서 Firefox 17.0을 테스트하는 경우 다음과 같은 루프를 받았습니다.

Benchmark example.

그런 게 아니라-- ""++비교 조작입니다.★★★★★★★★★★★★★★★★ --0의 할 수 .++츠키노프로세서에서는 보통 0과의 비교를 사용할 수 있지만 유한한 정수와의 비교에는 감산이 필요합니다.

a++ < length

실제로 컴파일되어 있다.

a++
test (a-length)

따라서 컴파일 시 프로세서에서 시간이 오래 걸립니다.

Sublime Text 2에서도 같은 추천을 본 적이 있습니다.

앞에서 설명한 바와 같이 주요 개선사항은 for 루프의 각 반복에서 어레이 길이를 평가하지 않는 것입니다.기술로 문서의 일부일 때 입니다.for 보나li★★★★★★★★★★★★★★★★★★」

예를들면,

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

보다 훨씬 느리다

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

때, 큰 변수예외 변수)를 입니다.len (이 예에서는)

제은 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아,i++ »i--그러나 각 반복에서 배열 길이를 평가할 필요가 없습니다(jperf에서 벤치마크 검정을 볼 수 있습니다).

단답

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

입니다.forloop 및 compare 스테이트먼트.

는 모든 고급 언어에 적용되며 대부분 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센트만.

높은 수준의 언어에서는 약간의 성능 향상으로 유지보수를 용이하게 하는 가독성이 더욱 중요합니다.

일반적으로 어레이 시작부터 끝까지 반복하는 이 좋습니다.

어레이의 끝에서 시작까지의 반복이 빨라지면 원치 않는 역순서가 발생할 수 있습니다.

투고 스크립트

멘트 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」--i ★★★★★★★★★★★★★★★★★」i--에서 입니다.i감소하기 전 또는 후에.

가장 좋은 설명은 시험해 보는 것입니다;-) 다음은 Bash의 입니다.

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

말을 이 안 것 요.i-- i++자바스크립트

우선 JavaScript 엔진 구현에 전적으로 의존합니다.

번째로, 가장 간단한 구조 J가IT는 네이티브 명령어로 번역되어 있습니다.i++ »i--CPU를 사용합니다. ARM가 실행되므로 이 빠릅니다.

아마도, 당신은 제안된 방법이 다른 방법보다 더 나쁘다고 생각했을 것이다.

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 엔진의 제한된 자산입니다.루프에서 사용되는 변수가 적을수록 확률 J가 많아집니다.IT부문은 최적화를 실현합니다.그래서...i--더 빨리 생각할 수 있을 것 같은데...

다른 답변은 모두 당신의 질문에 대한 답변이 아닌 것 같아서(반수 이상은 C의 예를 보여주고 낮은 수준의 언어에 대해 논의합니다), 저는 저만의 답변을 쓰기로 했습니다.

자, 여기 있습니다.

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

테스트 결과: 이 jsPerf에서 "실증"되었듯이,arr.pop()실제로 가장 빠른 루프입니다.근데 집중해서--i,i--,i++그리고.++i질문하신 바와 같이 jsPerf(복수의 jsPerf에서 가져온 것입니다. 아래 소스를 참조하십시오) 결과는 다음과 같습니다.

--i그리고.i--파이어폭스에서는 동일하지만i--크롬이 더 빠릅니다.

Chrome에서는 기본 for 루프(for (var i = 0; i < arr.length; i++))는, 보다 고속입니다.i--그리고.--i파이어폭스에서는 속도가 느립니다.

Chrome과 Firefox 모두 캐시된arr.length크롬이 약 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

이게 당신의 질문에 답하길 바랍니다.

이것은, 어레이의 메모리내의 배치와 그 어레이에 액세스 하고 있을 때의 메모리 페이지의 히트율에 의해서 다릅니다.

히트율이 증가하기 때문에 열 순서로 어레이 멤버에 액세스하는 것이 행 순서보다 빠를 수 있습니다.

마지막으로 신경이 쓰인 것은 6502 어셈블리(8비트, yeah!)를 쓸 때였습니다.가장 큰 이점은 대부분의 산술 연산(특히 감소)이 일련의 플래그를 업데이트하고, 그 중 하나가Z, '영점 0' 표시기.

루프의 마지막에, 다음의 2개의 순서를 실행했을 뿐입니다.DEC(설명) 및JNZ(0이 아니면 0), 비교할 필요가 없습니다!

지금 하고 있는 방법이 더 빠르지 않다(무한 루프라는 것 말고도, 당신은 그렇게 하려고 했겠죠).i--.

보다 빠르게 하려면 다음 작업을 수행합니다.

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

물론 그렇게 작은 루프에서는 알아채지 못할 겁니다.속도가 빠른 이유는 i가 "참"인지 확인하면서 감소하기 때문입니다(0이 되면 "거짓"으로 평가됨).

이는 JavaScript(및 모든 언어)로 설명할 수 있습니다.CPU는 항상 0과 비교하기 위한 하나의 명령어를 가지고 있어 매우 빠릅니다.

다른 한편으로, 당신이 보증할 수 있다면count항상 있다>= 0, 다음과 같이 심플화할 수 있습니다.

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

for(var i = array.length; i--; )그다지 빠르지는 않습니다.하지만 당신이 교체했을 때array.length와 함께super_puper_function()(모든 반복에서 호출되므로) 훨씬 더 빠를 수 있습니다.그게 차이점이에요.

2014년에 변경할 예정이라면 최적화를 생각하지 않아도 됩니다.Search & Replace(검색 & 치환)에서 변경할 경우 최적화에 대해 고려할 필요가 없습니다.시간이 없다면 최적화에 대해 생각할 필요가 없습니다.하지만 지금은 생각할 시간이 있어요.

추신:i--보다 빠르지 않다i++.

간단히 말하면:JavaScript 에서는 이 조작에 전혀 차이가 없습니다.

먼저 직접 테스트할 수 있습니다.

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

어느 환경에서나 성능에는 차이가 없습니다.

스크립트의 퍼포먼스를 향상시키고 싶은 경우는, 다음의 조작을 실행할 수 있습니다.

  1. 한 잔 하다var a = array.length;루프가 발생할 때마다 값을 계산하지 않도록 하기 위한 스테이트먼트
  2. http://en.wikipedia.org/wiki/Loop_unwinding의 루프 언롤을 실행합니다.

하지만 당신이 얻을 수 있는 개선은 매우 미미할 것이고, 대부분 그것에 대해 신경조차 쓰지 말아야 한다는 것을 알아야 한다.

왜 그런 오해가 생겼는지 (Dec vs Inc.)나만의 의견

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

이런 지식이 우리 시대에 전파될 수 있는 유일한 방법은 다른 사람의 개인 코드를 읽는 것이라고 생각합니다.이러한 구조를 보고 왜 구현되었는지를 물어보면 "0과 비교하여 성능이 향상됩니다."라는 답이 나옵니다.당신은 동료에 대한 더 높은 지식에 어리둥절해져서 그것을 훨씬 더 똑똑하게 사용하려고 생각합니다:-)

jsbench를 비교했습니다.

alestani가 지적한 바와 같이, 오름차순 루프에서 시간이 걸리는 한 가지 방법은 각 반복마다 어레이 크기를 평가하는 것입니다.이 루프에서는:

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];
}

가독성을 희생하지 않고 함수를 호출하는 대신 코드를 인라인화할 수 있으면 루프를 몇 배나 더 빠르게 만들 수 있습니다.


주의: 브라우저가 간단한 함수를 인라인화하는 데 능숙해짐에 따라 코드가 얼마나 복잡한지에 따라 달라집니다.최적화하기 전에 프로파일을 작성해야 합니다.

  1. 병목은 다른 곳(ajax, reflow 등)에 있을 수 있습니다.
  2. 더 나은 알고리즘을 선택할 수 있습니다.
  3. 더 나은 데이터 구조를 선택할 수 있습니다.

그러나 기억해:

코드는 사용자가 읽을 수 있도록 작성되어 있으며, 부수적으로 실행할 기계에만 적용됩니다.

이것은, 에 의존하지 않습니다.--아니면++부호는 루프에서 적용하는 조건에 따라 달라집니다.

예를 들어 다음과 같습니다.배열 길이 등 루프 체크 조건이 매번 있는 경우보다 변수가 정적 값을 갖는 경우 루프가 더 빠릅니다.

그러나 이 최적화에 대해서는 걱정하지 마십시오. 왜냐하면 이번에는 그 효과가 나노초 단위로 측정되기 때문입니다.

++대.--JavaScript는 컴파일된 언어가 아니라 해석된 언어이기 때문에 문제가 되지 않습니다.각 명령어는 둘 이상의 기계어로 번역되며, 번거로운 세부 사항은 신경 쓰지 마십시오.

사용하는 것에 대해 이야기하는 사람들은--(또는++)를 효율적으로 사용하는 것은 잘못된 것입니다.이 명령어는 정수 산술에 적용되며 JavaScript에는 정수가 없고 숫자만 있습니다.

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

예전에는 --i가 (C++에서) 더 빨랐다고 했습니다. 즉, 감소된 값은 i에 다시 저장해야 하고 원래 값도 유지해야 합니다(j = i--;).대부분의 컴파일러에서 이것은 하나의 레지스터가 아닌 두 개의 레지스터를 사용했고, 이로 인해 다른 변수가 레지스터 변수로 유지되지 않고 메모리에 기록되어야 할 수 있습니다.

나는 요즘 그것이 중요하지 않다고 말하는 다른 사람들의 말에 동의한다.

코드 작성 방법에 약간의 변경을 가하면 실제로 코드가 실행되는 속도에 큰 차이가 있을 수 있습니다.사소한 코드 변경으로 실행 시간에 큰 차이가 발생할 수 있는 영역 중 하나는 어레이를 처리하는 for 루프가 있는 영역입니다.웹 페이지의 요소(옵션 버튼 등)인 경우 변경은 가장 큰 영향을 미치지만, 어레이가 Javascript 코드 내부에 있는 경우에도 이 변경은 적용할 가치가 있습니다.

다음과 같이 배열 목록을 처리하도록 루프를 코드화하는 일반적인 방법은 다음과 같습니다.

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

이 문제의 문제는 myArray.length를 사용하여 어레이 길이를 평가하는 데 시간이 걸리고 루프를 코드화한 방법으로는 루프를 돌 때마다 이 평가를 수행해야 한다는 것입니다.어레이에 1000개의 요소가 포함되어 있는 경우 어레이 길이는 1001회 평가됩니다.myForm.myButtons.length 옵션버튼을 표시하고 있는 경우, 루프 주위를 돌 때마다 길이를 평가하려면 먼저 지정된 양식 내의 적절한 버튼 그룹을 찾아야 합니다.

처리 중에는 어레이의 길이가 변경될 것으로 예상하지 않기 때문에 이러한 길이의 재계산은 처리 시간을 불필요하게 늘릴 뿐입니다.(물론 루프 내에 어레이 엔트리를 추가하거나 삭제하는 코드가 있는 경우 어레이 크기는 반복 간에 변경될 수 있으므로 코드를 변경할 수 없습니다.t 테스트)

크기가 고정된 루프에 대해 이를 수정하려면 루프 시작 시 길이를 한 번 평가하여 변수에 저장합니다.그런 다음 변수를 테스트하여 루프를 종료할 시기를 결정할 수 있습니다.이는 특히 어레이에 몇 개 이상의 엔트리가 포함되어 있거나 웹 페이지의 일부인 경우 매번 어레이 길이를 평가하는 것보다 훨씬 빠릅니다.

이를 위한 코드는 다음과 같습니다.

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

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

어레이 내의 모든 엔트리가 처리되는 한 어레이를 어떤 순서로 처리해도 문제가 되지 않는 경우가 많습니다.이 경우 방금 추가한 변수를 삭제하고 어레이를 역순으로 처리함으로써 코드를 약간 더 빠르게 만들 수 있습니다.

어레이를 가능한 한 효율적으로 처리하는 마지막 코드는 다음과 같습니다.

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

이 코드는 여전히 처음에 어레이 크기를 한 번만 평가하지만 루프 카운터를 변수와 비교하는 대신 상수와 비교합니다.상수는 변수보다 액세스에 더욱 효과적이며, 3번째 버전의 코드보다 할당문이 하나 적기 때문에 이제 2번째 버전보다 약간 더 효율적이고 1번째 버전보다 훨씬 더 효율적입니다.

대부분의 경우 이는 프로세서가 다른 비교보다 빠르게 0과 비교할 수 있다는 사실과는 근본적으로 무관합니다.

이는 실제로 기계어 코드를 생성하는 Javascript 엔진(JIT 목록에 있는 엔진)이 적기 때문입니다.

대부분의 Javascript 엔진은 소스 코드의 내부 표현을 작성하고 이를 해석합니다(이것이 어떤 것인지 알기 위해서는 Firefox의 SpiderMonkey에서 이 페이지 하단을 참조하십시오).일반적으로 코드 조각이 실질적으로 동일한 작업을 수행하지만 내부 표현이 더 단순해지면 더 빠르게 실행됩니다.

변수에서 하나를 추가/감산하거나 변수를 다른 것과 비교하는 간단한 작업에서는 내부 "명령"에서 다음 "명령"으로 이동하는 인터프리터의 오버헤드가 상당히 높기 때문에 JS 엔진에 의해 내부적으로 사용되는 "명령"이 적을수록 좋다는 점에 유의하십시오.

JavaScript는 잘 모르겠습니다.어레이 길이를 재평가하고 관련 어레이와 관련된 문제일 뿐입니다(감소만 하면 새로운 엔트리를 할당할 필요가 없습니다.즉, 어레이 밀도가 높은 경우에는 누군가가 이를 위해 최적화할 수 있습니다.

로우 레벨 어셈블리에는 DJNZ(감속 및 0이 아닌 경우 점프)라고 하는 루프 명령이 있습니다.따라서 감소와 점프는 모두 하나의 명령으로 이루어지므로 INC 및 JL/JB보다 약간 더 빠를 수 있습니다(증가, 이하이면 점프, 이하이면 점프).또한 0과 비교하는 것이 다른 숫자와 비교하는 것보다 쉽습니다.그러나 이 모든 것은 매우 미미하며 대상 아키텍처에 따라 달라집니다(스마트폰의 Arm 등).

이 낮은 수준의 차이가 통역 언어에 그렇게 큰 영향을 미칠 것이라고는 예상하지 못했습니다.그냥 DJNZ를 본 적이 없기 때문에 재미있는 생각을 공유해야겠다고 생각했습니다.

간단히 말하면

"i-그리고 i++"사실 둘 다 같은 시간이 걸린다.

하지만 이 경우에는 증분 연산이 있을 때..processor는 변수가 1씩 증가할 때마다 .length를 평가하며 감소하는 경우에는 .length를 평가합니다.특히 이 경우 .length는 0이 될 때까지 한 번만 평가됩니다.

첫번째,i++그리고.i--JavaScript를 포함한 모든 프로그래밍 언어에서 동일한 시간을 사용할 수 있습니다.

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

고속:

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] };

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

i-또는 i++에 의해 소비되는 시간은 많지 않습니다.CPU 아키텍처의 상세 내용을 살펴보면++보다 빠르다--, 그 이후로--동작은 2의 보완이 되지만 하드웨어 내부에서 발생했기 때문에 고속으로 동작할 수 있고, 그 사이에 큰 차이는 없습니다.++그리고.--또, 이러한 조작은, CPU 로 소비되는 최소의 시간으로 간주됩니다.

for 루프는 다음과 같이 동작합니다.

  • 변수를 시작할 때 한 번 초기화합니다.
  • 루프의 두 번째 피연산자의 구속조건을 확인합니다.<,>,<=,기타.
  • 그런 다음 루프를 적용합니다.
  • 루프를 증가시키고 루프를 반복하여 이들 프로세스를 다시 슬로우합니다.

그렇게,

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

는 처음에 어레이 길이를 1회만 계산하고 이 시간은 많지 않습니다만,

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

는 각 루프에서 길이를 계산하기 때문에 많은 시간이 소요됩니다.

이런 질문에 대답하는 가장 좋은 방법은 실제로 해보는 것입니다.루프를 100만 번 세거나 하는 식으로 설정합니다.양쪽 루프의 시간을 재어 결과를 비교합니다.

답은 사용하고 있는 브라우저에 따라 다를 수 있습니다.어떤 사람들은 다른 사람들과 다른 결과를 얻을 것이다.

마음에 들어, 많은 점수가 올랐지만 답이 없어: D

간단히 말해 0과 비교하는 것이 항상 가장 빠른 비교입니다.

따라서 실제로 (a==0)이 (a==5)보다 True를 더 빨리 반환합니다.

작고 하찮으며 1억 개의 행이 수집되어 있어 측정할 수 있습니다.

즉, 루프업 시 i <= array.length가 어디에 있는지 알려주고 i가 증가합니다.

다운 루프에서는 i > = 0의 위치를 나타내고 대신 i가 감소하는 경우가 있습니다.

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

다른 사람이 두통을 피할 수 있도록 도와주세요.- 투표해 주세요!!!

이 페이지에서 가장 많이 사용되는 답변은 Firefox 14에서 작동하지 않으며 jsLinter를 통과하지 않습니다.while 루프에는 할당이 아닌 비교 연산자가 필요합니다.크롬, 사파리, 심지어 ie에서도 작동합니다.하지만 파이어폭스에서 죽어요

이건 고장났어!

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

이것은 동작합니다! (firefox에서 동작하며 jsLinter를 통과합니다.)

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

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

언급URL : https://stackoverflow.com/questions/1340589/are-loops-really-faster-in-reverse

반응형