루프가 반대로 더 빠릅니까?
나는 이것을 꽤 많이 들었다. 역으로 계산할 때 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++
++i
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 와 같은 고급 언어의 관점 에서 라이브러리를 사용하는 경우 루프를위한 내장 함수를 최적화 할 수 있습니다. 최선의 방법을 결정하게하십시오.
결과적으로 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
사용할 수 없거나 다른 복잡한 라이브러리 함수. ;)
i--
~만큼 빠르다 i++
아래 코드는 귀하의 것보다 빠르지 만 추가 변수를 사용합니다.
var up = Things.length;
for (var i = 0; i < up; i++) {
Things[i]
};
권장 사항은 매번 어레이의 크기를 평가하지 않는 것입니다. 큰 어레이의 경우 성능 저하를 볼 수 있습니다.
주제에 관심이 있으니 JavaScript 루프 벤치 마크인 JavaScript에서 루프를 코딩 하는 가장 빠른 방법은 무엇입니까 에 대한 Greg Reimer의 웹 로그 게시물을 살펴보십시오 . :
JavaScript에서 루프를 코딩하는 다양한 방법을위한 루프 벤치마킹 테스트 스위트를 구축했습니다. 이미 몇 가지가 있지만 네이티브 배열과 HTML 컬렉션의 차이점을 인정하는 것을 찾지 못했습니다.
또한 열어서 루프에서 성능 테스트를 수행 할 수 있습니다 https://blogs.oracle.com/greimer/resource/loop-test.html
(예 : NoScript 등으로 브라우저에서 JavaScript가 차단 된 경우 작동하지 않음 ).
편집하다:
Milan 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;
}
--
또는 아닌 ++
, 비교 작업입니다. 를 사용 --
하면 0과 비교를 사용할 수 있지만 ++
길이와 비교해야합니다. 프로세서에서 0과 비교는 일반적으로 사용 가능하지만 유한 정수와 비교하려면 빼기가 필요합니다.
a++ < length
실제로 다음과 같이 컴파일됩니다
a++
test (a-length)
따라서 컴파일 할 때 프로세서에서 시간이 더 걸립니다.
짧은 대답
일반 코드, 특히 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 센트 만
고급 언어의 경우 약간의 성능 향상으로 유지 관리가 용이 한 가독성이 더 중요합니다.
일반적으로 배열 시작부터 끝까지 고전적인 반복 이 더 좋습니다.
배열 끝에서 시작하여 반복이 빠를 수록 원하지 않는 반전 순서가 발생할 수 있습니다.
포스트 스크립트
의견에서 물었 듯이 : 감소 전후 의 차이점 --i
과 i--
평가에 i
있습니다.
가장 좋은 설명은 시도해 보는 것입니다. ;-) 여기 Bash 예제가 있습니다.
% i=10; echo "$((--i)) --> $i"
9 --> 9
% i=10; echo "$((i--)) --> $i"
10 --> 9
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 에서 벤치 마크 테스트를 볼 수 있음 ).
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--
더 빠르게 고려할 수 있습니다 ...
다른 답변은 귀하의 특정 질문에 답변하지 않는 것 같습니다 (그중 절반 이상이 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
이것이 귀하의 질문에 답변되기를 바랍니다.
메모리에 어레이를 배치하고 해당 어레이에 액세스하는 동안 메모리 페이지의 적중률에 따라 다릅니다.
경우에 따라 적중률 증가로 인해 열 순서로 배열 멤버에 액세스하는 것이 행 순서보다 빠릅니다.
6502 어셈블리 (8 비트, 예!)를 작성할 때 마지막으로 신경 쓰지 않았습니다 . 가장 큰 이득은 대부분의 산술 연산 (특히 감소)이 플래그 세트를 업데이트했다는 것 Z
입니다.
따라서 루프가 끝나면 DEC
(감소)와 JNZ
(0이 아닌 경우 점프 ) 두 가지 명령을 수행했습니다. 비교가 필요하지 않습니다!
간단히 말하면 : JavaScript 에서이 작업을 수행하는 데 아무런 차이가 없습니다.
우선, 직접 테스트 할 수 있습니다.
JavaScript 라이브러리에서 스크립트를 테스트하고 실행할 수있을뿐만 아니라 이전에 작성된 모든 스크립트에 액세스 할 수있을뿐만 아니라 다른 플랫폼의 다른 브라우저에서 실행 시간의 차이를 확인할 수 있습니다.
보시다시피, 어떤 환경에서도 성능에는 차이가 없습니다.
스크립트 성능을 향상 시키려면 다음을 수행하십시오.
- 가지고
var a = array.length;
당신이 루프에서 값마다 계산되지 않도록 문을 - 루프 풀기 http://en.wikipedia.org/wiki/Loop_unwinding
그러나 얻을 수있는 개선은 그다지 중요하지 않으므로 대부분 신경 쓰지 않아도된다는 것을 이해해야합니다.
왜 그런 오해 (Dec vs Inc)가 나타 났는지에 대한 내 의견
오래 전부터 일반적인 기계 명령어 인 DSZ (Decrement and Skip on Zero)가있었습니다. 어셈블리 언어로 프로그래밍 한 사람들은 레지스터를 저장하기 위해이 명령어를 사용하여 루프를 구현했습니다. 이제이 고대 사실은 더 이상 사용되지 않으며이 의사 개선을 사용하여 어떤 언어로도 성능 향상을 얻지 못할 것이라고 확신합니다.
우리 시대에 그러한 지식이 전파 될 수있는 유일한 방법은 다른 사람의 사람 코드를 읽는 것입니다. 이러한 구성을보고 구현 된 이유와 여기에 "제로에 비해 성능이 향상됩니다"라는 대답이 표시됩니다. 당신은 당신의 동료에 대한 더 높은 지식에 당황하게되었고 훨씬 똑똑하게 사용하려고 생각합니다 :-)
JavaScript (및 모든 언어)가 결국 CPU에서 실행되도록 opcode로 바뀌는 것으로 설명 할 수 있습니다. CPU는 항상 0과 비교하기위한 단일 명령을 가지고 있으며, 이는 매우 빠릅니다.
제쳐두고, count
항상 보장 할 수 있다면 >= 0
, 다음과 같이 단순화 할 수 있습니다
for (var i = count; i--;)
{
// whatever
}
이것은 --
또는 ++
부호 에 의존하지 않지만 루프에서 적용하는 조건에 따라 다릅니다.
예를 들어, 루프 길이가 배열의 길이나 다른 조건과 같이 매번 조건을 확인하는 것보다 변수에 정적 값이 있으면 루프가 더 빠릅니다.
그러나 이번 최적화는 나노초 단위로 측정되므로이 최적화에 대해 걱정하지 마십시오.
for(var i = array.length; i--; )
훨씬 빠르지 않습니다. 바꿀 때 array.length
에 super_puper_function()
, 그것은있을 수 있습니다 크게 (이 모든 반복에서라고 때문에) 더 빨리. 그 차이입니다.
2014 년에 변경하려는 경우 최적화에 대해 생각할 필요가 없습니다. "검색 및 바꾸기"로 변경하려는 경우 최적화에 대해 생각할 필요가 없습니다. 시간이 없다면 최적화에 대해 생각할 필요가 없습니다. 그러나 지금, 당신은 그것에 대해 생각할 시간이 있습니다.
PS : i--
보다 빠르지 않습니다 i++
.
내가 만든 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 배 빠르게 처리 할 수 있습니다!
참고 : 브라우저가 간단한 함수 를 인라인하는 데 능숙 해짐에 따라 코드의 복잡도에 따라 달라집니다. 따라서 최적화하기 전에 프로필을 작성하십시오.
- 병목 현상이 다른 곳 (아약스, 리플 로우 등) 일 수 있습니다.
- 더 나은 알고리즘을 선택할 수 있습니다
- 더 나은 데이터 구조를 선택할 수 있습니다
하지만 기억해:
사람들이 읽을 수 있도록 기계가 실행되도록 코드가 작성됩니다.
당신이 지금하고있는 방식은 더 빠르지 않습니다 (무한한 루프를 제외하고는, 당신이해야 할 것으로 생각합니다 i--
.
더 빨리 만들고 싶다면 :
for (i = 10; i--;) {
//super fast loop
}
물론 작은 루프에서는 눈치 채지 못할 것입니다. 더 빠른 이유는 "true"인지 확인하면서 i를 감소시키기 때문입니다 (0에 도달하면 "false"로 평가됨).
때때로 코드를 작성하는 방식을 약간만 변경하면 코드가 실제로 얼마나 빨리 실행되는지 크게 달라질 수 있습니다. 사소한 코드 변경으로 인해 실행 시간이 크게 달라질 수있는 영역은 배열을 처리하는 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--) {...
이 코드는 여전히 시작시 한 번만 배열의 크기를 평가하지만 루프 카운터를 변수와 비교하는 대신 상수와 비교합니다. 상수는 변수보다 액세스하는 것이 훨씬 효과적이며 코드의 세 번째 버전보다 이전에 하나의 할당 문이 적기 때문에 두 번째 버전보다 약간 효율적이고 첫 번째 버전보다 훨씬 더 효율적입니다.
++
대는 --
자바 스크립트 인터프리터 언어가 아닌 컴파일 된 언어이기 때문에 문제가되지 않습니다. 각 명령어는 둘 이상의 기계 언어로 번역되므로 사용자는 세부 사항에 신경 쓰지 않아야합니다.
조립 지침을 효율적으로 사용하기 위해 --
(또는 ++
)를 사용하는 것에 대해 말하는 사람들 은 잘못되었습니다. 이 명령어는 정수 산술에 적용 되며 JavaScript에는 정수가 아니라 숫자 만 있습니다 .
읽을 수있는 코드를 작성해야합니다.
많은 경우에, 이것은 프로세서가 다른 비교보다 0과 더 빠르게 비교할 수 있다는 사실과 본질적으로 관련이 없습니다.
때문입니다 몇 자바 스크립트 엔진 (JIT를 목록에있는 사람)이 실제로 기계어 코드를 생성합니다.
대부분의 Javascript 엔진은 소스 코드의 내부 표현을 작성한 다음 해석합니다 (이것이 어떤 것인지 알기 위해 Firefox의 SpiderMonkey의이 페이지 하단 부근을보십시오 ). 일반적으로 코드 조각이 실제로 동일한 기능을 수행하지만 내부 표현이 단순 해지면 더 빨리 실행됩니다.
변수에서 변수를 더하거나 빼는 것과 같은 간단한 작업이나 변수를 무언가와 비교하는 것과 같이, 하나의 내부 "지시"에서 다음으로 이동하는 인터프리터의 오버 헤드는 상당히 높기 때문에 "지시"가 적다는 것을 명심하십시오. JS 엔진에서 내부적으로 사용하면 좋습니다.
글쎄, 나는 JavaScript에 대해 모른다. 실제로 배열 길이를 재평가해야하고 연관 배열과 관련이있을 것이다. 배열은 밀도가 높습니다. 즉 누군가가 그것을 최적화 할 수 있습니다).
저수준 어셈블리에는 DJNZ (0이 아닌 경우 감소 및 점프)라는 루핑 명령어가 있습니다. 따라서 감소 및 점프는 모두 하나의 명령으로 이루어지며 INC 및 JL / JB보다 약간 빠릅니다 (증가, 아래의 경우 / 점프보다 작 으면 점프). 또한 0과 비교하는 것이 다른 숫자와 비교하는 것보다 간단합니다. 그러나 실제로는 거의 한계가 있으며 대상 아키텍처에 달려 있습니다 (예 : 스마트 폰의 팔에 차이를 만들 수 있음).
이 낮은 수준의 차이가 해석 된 언어에 큰 영향을 줄 것으로 기대하지는 않을 것입니다. 응답 중 DJNZ를 보지 못했기 때문에 흥미로운 생각을 공유 할 것이라고 생각했습니다.
그것은 사용 하나만 결과, 감소 된 값이 있기 때문에 (C ++에서) --i 빠른 것을 상기한다. i-- 감소 된 값을 다시 i로 저장하고 원래 값을 결과로 유지해야합니다 (j = i--;). 대부분의 컴파일러에서 이것은 하나의 레지스터가 아닌 두 개의 레지스터를 사용하여 레지스터 변수로 유지되지 않고 다른 변수를 메모리에 쓰도록 할 수 있습니다.
나는 요즘 차이가 없다고 말한 다른 사람들에게 동의합니다.
아주 간단한 말로
"i--와 i ++. 사실 둘 다 같은 시간이 걸립니다".
그러나이 경우 증분 연산이있는 경우. 프로세서는 변수가 1 씩 증가 할 때마다 .length를 평가하고 감소하는 경우 특히 .length가 0이 될 때까지 한 번만 평가합니다.
먼저, 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--'를 사용하는 것 입니다.
i- 또는 i ++는 많은 시간을 소비하지 않습니다. 당신은 CPU 아키텍처 내부에 깊이 갈 경우는 ++
댄 더 빠른이다 --
때문에 --
작업이 2의 보수를 할 것입니다,하지만 그것은 신속하고 사이에 큰 차이 만들 것입니다 그래서 하드웨어 내부에 무슨 일이 생긴 ++
하고 --
이러한 작업이로 간주됩니다 CPU에서 가장 적은 시간.
루프는 다음과 같이 실행합니다 :
- 시작시 변수를 한 번 초기화하십시오.
- 루프의 두 번째 피연산자에 제약 조건을 확인,
<
,>
,<=
, 등 - 그런 다음 루프를 적용하십시오.
- 루프를 증가시키고 루프는 다시이 프로세스를 던집니다.
그래서,
for (var i = Things.length - 1; i >= 0; i--) {
Things[i]
};
시작시 한 번만 배열 길이를 계산하며 많은 시간이 걸리지 않지만
for(var i = array.length; i--; )
각 루프에서 길이를 계산하므로 많은 시간이 소요됩니다.
이런 종류의 질문에 대답하는 가장 좋은 방법은 실제로 시도하는 것입니다. 백만 번의 반복 횟수를 계산하는 루프를 설정하고 두 가지 방법으로 수행하십시오. 두 루프의 시간을 정하고 결과를 비교하십시오.
대답은 사용중인 브라우저에 따라 다를 수 있습니다. 일부는 다른 결과와 다릅니다.
그것을 사랑하지만, 마크가 많지만 대답이 없습니다 : D
단순히 0과 비교하면 항상 가장 빠른 비교입니다
따라서 (a == 0)은 실제로 (a == 5)보다 True를 반환 할 때 더 빠릅니다.
작고 중요하지 않으며 컬렉션에 1 억 개의 행이있어 측정 가능합니다.
즉, 루프 업하면 i <= array.length라고 말하고 i를 증가시킬 수 있습니다.
다운 루프에서 i> = 0이라고 말하고 대신 i를 줄입니다.
비교가 더 빠릅니다. 루프의 '방향'이 아닙니다.
다른 사람들은 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;
}
이것은 추측에 불과하지만 프로세서가 다른 값 (i <Things.length) 대신 0 (i> = 0)과 비교하는 것이 더 쉽기 때문일 수 있습니다.
참고 URL : https://stackoverflow.com/questions/13136724/why-is-i-faster-than-i-in-loops
'IT story' 카테고리의 다른 글
프로그래밍 방식으로 텍스트 색상을 텍스트보기로 설정하는 방법 (0) | 2020.04.15 |
---|---|
'git diff'가 변경된 파일 이름과 줄 번호 만 표시하도록 할 수 있습니까? (0) | 2020.04.15 |
가장 널리 사용되는 C ++ 벡터 / 행렬 수학 / 선형 대수 라이브러리는 무엇이고 비용과 이점은 무엇입니까? (0) | 2020.04.15 |
레포 틴이란 무엇이며 어떻게 작동합니까? (0) | 2020.04.15 |
내 HttpClient PostAsync 두 번째 매개 변수에 대해 HttpContent를 어떻게 설정합니까? (0) | 2020.04.15 |