자바스크립트에서 Typed Arrays의 장점은 C에서 작동하는 것과 같거나 비슷하다는 것입니까?
자바스크립트로 타이핑된 배열을 가지고 놀았습니다.
var buffer = new ArrayBuffer(16);
var int32View = new Int32Array(buffer);
일반적인 배열을 상상합니다.[1, 257, true])자바스크립트에서는 그들의 값이 어떤 종류이든 될 수 있기 때문에 성능이 좋지 않습니다. 따라서 메모리에서 오프셋에 도달하는 것은 사소하지 않습니다.
저는 원래 자바스크립트 배열 첨자가 객체와 동일하게 작동하며(유사한 점이 많기 때문에) 해시 맵 기반이므로 해시 기반 조회가 필요하다고 생각했습니다.하지만 이를 확인할 만한 신빙성 있는 정보를 많이 찾지 못했습니다.
따라서 Typed Arrays가 매우 뛰어난 성능을 보이는 이유는 항상 Typed를 사용하는 C의 일반 어레이와 같이 작동하기 때문이라고 생각합니다.위의 초기 코드 예제를 고려할 때, 그리고 타이핑된 배열에서 10번째 값을 얻고자 하는...
var value = int32View[10];
- 유형은
Int32, 따라서 각 값은 다음과 같이 구성되어야 합니다.32작은 것들4바이트 수 - 구독자는
10. - 그래서 그 값을 기억하는 위치는
<array offset> + (4 * 10), 그리고 읽습니다.4총 값을 가져올 바이트 수 있습니다.
저는 기본적으로 제 가정을 확인하고 싶습니다.이에 대한 제 생각이 맞습니까? 만약 그렇지 않다면 자세히 설명해 주십시오.
제가 직접 답변을 할 수 있는지 V8 소스를 확인해 보았는데, 제 C가 녹슬어서 C++를 잘 모릅니다.
Type Array는 성능상의 이유로 WebGL 표준 위원회에서 설계하였습니다.일반적으로 자바스크립트 배열은 일반적이며 객체, 다른 배열 등을 담을 수 있습니다. 그리고 요소들은 C에 있는 것처럼 메모리에서 반드시 순차적인 것은 아닙니다.WebGL은 메모리에서 버퍼가 순차적이어야 하는데, 이는 기본적인 C API가 버퍼를 예상하기 때문입니다.Type Array를 사용하지 않는 경우 일반 배열을 WebGL 함수에 전달하려면 많은 작업이 필요합니다. 각 요소를 검사하고, 유형을 검사한 다음, 올바른 작업(예: Float)이면 별도의 순차적 C-like 버퍼에 복사한 다음, 해당 순차적 버퍼를 C API로 전달합니다.아, 수고 많으시다!성능에 민감한 WebGL 애플리케이션의 경우 프레임 속도가 크게 저하될 수 있습니다.
반면, 질문에서 제시한 것처럼 Typed Array는 비하인드 스토리지에 이미 순차적인 C-like 버퍼를 사용합니다.입력된 배열에 쓸 때는 정말로 뒤에 있는 C 같은 배열에 할당하는 것입니다.WebGL의 목적상 버퍼는 해당 CAPI에서 직접 사용할 수 있습니다.
메모리 주소 계산이 충분하지 않습니다. 브라우저는 배열을 경계 검사하여 범위를 벗어난 액세스를 방지해야 합니다.이는 모든 종류의 자바스크립트 배열에서 발생해야 하지만, 영리한 자바스크립트 엔진은 인덱스 값이 이미 경계 내에 있다는 것을 증명할 수 있을 때 체크를 생략할 수 있습니다(예를 들어 배열의 길이가 0인 루프).또한 배열 인덱스가 문자열이나 다른 것이 아니라 실제로 숫자인지 확인해야 합니다!하지만 그것은 본질적으로 당신이 설명한 것처럼 C 같은 주소를 사용합니다.
하지만.. 그게 다가 아닙니다!어떤 경우에는 영리한 자바스크립트 엔진이 일반 자바스크립트 배열의 종류를 추론할 수도 있습니다.V8과 같은 엔진에서 일반적인 자바스크립트 배열을 만들고 그 안에 플로트만 저장한다면 V8은 플로트 배열이라고 낙관적으로 판단하고 이를 위해 생성하는 코드를 최적화할 수 있습니다.그러면 유형화된 배열과 같은 성능을 발휘할 수 있습니다.따라서 유형화된 어레이는 성능을 극대화하기 위해 실제로 필요하지 않습니다. (모든 요소가 동일한 유형으로) 예측 가능하게 어레이를 사용하고 일부 엔진은 이를 최적화할 수도 있습니다.
그렇다면 유형화된 어레이가 여전히 존재해야 하는 이유는 무엇일까요?
- 어레이 유형 추론과 같은 최적화 작업은 매우 복잡합니다.V8이 일반 어레이에 플로트만 있는 것으로 추론한 다음 요소에 개체를 저장하면 해당 어레이를 일반화하는 코드를 다시 최적화 해제하고 재생성해야 합니다.이 모든 것이 투명하게 작동한다는 것은 상당한 성과입니다.Type Array는 한 가지 유형이 보장되므로 개체와 같은 다른 것을 저장할 수 없습니다.
- 최적화는 결코 보장되지 않습니다. 일반 배열에 플로트만 저장할 수 있지만 엔진은 최적화하지 않는 여러 가지 이유로 결정할 수 있습니다.
- 훨씬 간단하다는 사실은 다른 덜 복잡한 자바스크립트 엔진들도 쉽게 구현할 수 있다는 것을 의미합니다.이들에게는 고도의 최적화 해제 지원이 필요하지 않습니다.
- 실제 고급 엔진을 사용하더라도 최적화를 사용할 수 있다는 것을 증명하는 것은 매우 어렵고 때로는 불가능할 수도 있습니다.유형화된 배열은 엔진이 주변을 최적화하는 데 필요한 증명 수준을 대폭 간소화해 줍니다.유형 배열에서 반환되는 값은 확실히 특정 유형이며 엔진은 해당 유형의 결과를 최적화할 수 있습니다.일반 배열에서 반환되는 값은 이론적으로 어떤 형식이든 가질 수 있으며, 엔진은 항상 같은 형식 결과를 가질 것이라는 것을 증명할 수 없을 수 있으므로 효율성이 떨어지는 코드를 생성합니다.따라서 유형 배열 주위의 코드가 보다 쉽게 최적화됩니다.
- 배열을 입력하면 실수할 수 있는 기회가 사라집니다.실수로 개체를 저장할 수 없어 갑자기 성능이 크게 저하될 수 있습니다.
간단히 말해서, 일반 어레이는 이론적으로 타이핑된 어레이와 동일하게 빠를 수 있습니다.그러나 유형화된 어레이를 사용하면 최고 성능에 훨씬 쉽게 도달할 수 있습니다.
네, 대부분 맞습니다.표준 자바스크립트 배열의 경우, 자바스크립트 엔진은 배열의 데이터가 모든 개체라고 가정해야 합니다.메모리에 대한 액세스가 설명한 것과 동일한 C-like 배열/벡터로 저장할 수 있습니다.문제는 데이터가 값이 아니라 그 값(객체)을 참조하는 것이라는 것입니다.
그래서 공연을.a[i] = b[i] + 2엔진에 필요한 작업:
- bat index i의 객체에 접근합니다;
- 물체가 어떤 종류인지 확인합니다.
- 개체에서 값을 추출합니다.
- 값에 2를 더합니다.
- 새로 계산된 값을 4에서 사용하여 새 객체를 만듭니다.
- 5단계의 새 개체를 at index i에 할당합니다.
유형 배열을 사용할 경우 엔진은 다음을 수행할 수 있습니다.
- bat index i(CPU 레지스터에 위치시키는 것을 포함)의 값에 접근합니다.
- 값을 2씩 증가시킵니다.
- 2단계의 새 개체를 at index i에 할당합니다.
참고: 컴파일 중인 코드(주변 코드 포함)와 해당 엔진에 따라 달라지므로 자바스크립트 엔진이 수행할 정확한 단계는 아닙니다.
이를 통해 결과 계산이 훨씬 더 효율적이 될 수 있습니다.또한, 타이핑된 어레이는 메모리 레이아웃 보증(n바이트 값의 어레이)을 갖추고 있으므로 데이터(오디오, 비디오 등)와 직접 인터페이스할 수 있습니다.
성능에 관한 한, 상황은 빠르게 변할 수 있습니다.AshleyBrain이 말한 것처럼, VM이 일반 어레이를 빠르고 정확하게 유형 어레이로 구현할 수 있다는 것을 추론할 수 있는지 여부에 달려 있습니다.이는 특정 JavaScript VM의 특정 최적화에 따라 달라지며, 새로운 브라우저 버전에서는 변경할 수 있습니다.
이 Chrome 개발자 의견은 2012년 6월 기준으로 작동한 몇 가지 지침을 제공합니다.
- 일반 어레이는 연속 액세스를 많이 수행할 경우 타이핑된 어레이만큼 빠를 수 있습니다.배열의 경계를 벗어난 랜덤 액세스는 배열을 증가시킵니다.
- 유형화된 배열은 액세스 속도는 빠르지만 할당 속도는 느립니다.임시 배열을 자주 생성하는 경우에는 유형화된 배열을 사용하지 마십시오. (이 문제를 해결하는 것은 가능하지만 우선 순위가 낮습니다.)
- JSPerf와 같은 마이크로 벤치마크는 실제 성능에 대해 신뢰할 수 없습니다.
마지막 사항을 좀 더 자세히 설명하자면, 저는 자바에서 이 현상을 수년간 보아왔습니다.작은 코드 조각을 분리된 상태에서 반복적으로 실행하여 테스트하면 VM이 코드 조각의 속도를 최적화합니다.특정 테스트에만 적합한 최적화를 제공합니다.벤치마크는 다른 프로그램 내에서 동일한 코드를 실행하거나, 동일한 코드를 다르게 최적화하는 여러 테스트를 실행한 후 즉시 실행하는 것과 비교하여 100배의 속도 향상을 얻을 수 있습니다.
저는 자바스크립트 엔진에 별로 기여하지 않습니다. v8에 대한 판독값이 조금밖에 없어서 제 대답이 완전히 사실이 아닐 수도 있습니다.
어레이의 우수한 값(홀/갭이 없고 희소하지 않은 일반 어레이만 해당).희소 배열은 개체로 취급됩니다.)는 모두 포인터이거나 고정된 길이를 가진 숫자입니다(v8에서 32비트입니다. 31비트 정수인 경우 a로 태그가 지정됩니다).0bit in the end, 그렇지 않으면 포인터).
따라서 메모리 위치를 찾는 것은 어레이 전체에서 바이트 수가 동일하기 때문에 typeArray와 다르지 않다고 생각합니다.그러나 개체일 경우 하나의 압축 해제 레이어를 추가해야 하는데, 이는 일반적인 유형의 Array에서는 발생하지 않습니다.
물론 typeArray에 액세스할 때 일반 배열이 가지고 있는 type checking이 확실히 없습니다(hot code에 대해서만 생성되는 고도로 최적화된 코드에서는 제거될 수 있지만).
Writing의 경우, 같은 유형이면 속도가 많이 느리지 않아야 합니다.다른 유형이면 JS 엔진이 이에 대한 다형성 코드를 생성할 수 있으며, 이는 더 느립니다.
확인을 위해 jsperf.com 에서 몇 가지 벤치마크를 만들어 볼 수도 있습니다.
언급URL : https://stackoverflow.com/questions/13328658/are-the-advantages-of-typed-arrays-in-javascript-is-that-they-work-the-same-or-s
'programing' 카테고리의 다른 글
| 제거한다.제거한다.wp_nav_메뉴 출력에서 포장지 (0) | 2023.11.04 |
|---|---|
| HTML5 오디오 재생 여부 확인? (0) | 2023.11.04 |
| JQuery를 사용하여 특정 자식 요소가 없는 요소를 선택하는 방법 (0) | 2023.11.04 |
| PHP를 사용하여 압축과 함께 PNG를 JPG로 변환하시겠습니까? (0) | 2023.11.04 |
| ELSIF V/S가 오라클에 있는 경우 (0) | 2023.11.04 |