기본 ES6 약속이 블루 버드보다 느리고 메모리를 많이 사용하는 이유는 무엇입니까?


195

에서 이 벤치 마크 , 스위트 블루 버드 약속에 비해 ES6의 약속으로 완료하는 데 4 시간 이상 소요되며, 메모리의 3.6 배를 사용합니다.

JavaScript 라이브러리가 C로 작성된 v8의 기본 구현보다 훨씬 빠르고 가벼운 방법은 무엇입니까? 블루 버드 약속은 기본 ES6 약속과 정확히 동일한 API (및 추가 유틸리티 메소드)를 갖습니다.

기본 구현이 잘못 작성되었거나 누락 된 다른 측면이 있습니까?


최신 JavaScript 구현은 크게 최적화되어 있으며 JIT를 사용하여 기본적으로 실행될 수도 있습니다 .

1
이 벤치 마크 에 따르면 BlueBirdJS는 기본 약속보다 실제로 느립니다. 그러나 PromiseMeSpeedJS는 실제로 두 가지를 능가합니다. PromiseMeSpeedJS가이를 통해 입증하는 많은 것들 중 하나는 newPromiseMeSpeedJS가 사용하지 않기 때문에 약속의 주요 성능 원인은 운영자의 과도한 사용이라는 것 new입니다.
Jack Giffin

1
@JackGiffin Chrome 67 : PromiseMeSpeedJS는 46 % 느리고 블루 버드는 61 % 느립니다.
FINDarkside

답변:


272

블루 버드 작가.

V8은 구현이 C가 아닌 JavaScript로 작성되도록 약속합니다 . V8을 포함한 모든 JavaScript는 기본 코드로 컴파일됩니다. 또한 사용자 작성 JavaScript는 가능한 경우 기본 코드로 컴파일되기 전에 최적화됩니다 (그리고 가치가있는 경우). 약속 한 구현은 C로 작성되어 많은 이익을 얻지 못하거나 전혀 이익이되지 않는 것입니다. 실제로 JavaScript 객체와 통신을 조작하기 때문에 속도가 느려집니다.

V8 구현은 단순히 블루 버드만큼 최적화되지 않았으며, 예를 들어 promises 핸들러에 배열을 할당합니다 . 각 약속에 두 개의 배열을 할당해야 할 때 많은 메모리가 필요합니다 (벤치 마크는 전체 80k 약속을 생성하여 160k 미사용 배열이 할당 됨). 실제로 99.99 %의 사용 사례는 약속을 두 번 이상 분기하지 않으므로이 일반적인 경우를 최적화하면 메모리 사용량이 크게 향상됩니다.

V8이 블루 버드와 동일한 최적화를 구현하더라도 사양에 의해 여전히 방해를받습니다. new PromiseES6에는 근본적인 약속을 만들 수있는 다른 방법이 없으므로 벤치 마크 (블루 버드의 안티 패턴) 를 사용해야 합니다. new Promise는 약속을 만드는 매우 느린 방법입니다. 먼저 executor 함수가 클로저를 할당하고 두 번째로 두 개의 별도 클로저가 인수로 전달됩니다. 약속 당 3 개의 폐쇄가 할당되었지만 폐쇄는 이미 최적화 된 약속보다 더 비싼 개체입니다.

Bluebird를 사용 promisify하면 많은 최적화가 가능하고 콜백 API를 소비하는 훨씬 편리한 방법이며 전체 모듈을 한 줄에 약속 기반 모듈로 변환 할 수 있습니다 ( promisifyAll(require('redis'));).


10
"여전히 사양에 의해 방해 받는다"-그 의미가 무엇인지 잘 모르겠습니다. ES6이 본질적으로 느린 사양을 따르고 있다고 말하고 있습니까? 그렇다면 블루 버드가 동일한 사양을 따르지 않는다는 것을 의미합니까? 그리고 ES6가 루트 약속을 만드는 더 좋은 방법을 갖지 못 new Promise하거나 인스턴스화를 개선하여 더 저렴하게 만드는 이유가 있습니까?
Anthony

12
JS의 경우 전혀 들리지 않습니다. 내부 구현이있을 때 Promise 라이브러리를 사용하고 싶지 않습니다. 이것이 사실이라면 모두에게 불행한 상황이 아닙니다. 그러나 나는 이미 모든 경우에 아주 사소한 개선이다, 나는 10 만 개 LoC JS 응용 프로그램을 작성했습니다 내가 아직 이것에 대한 실제 필요를 보지 않는다, 어쨌든 문제가 약속 - 과대 광고를보고이 나에게 아니, 대부분의 오류 처리에, 콜백 처리의 개선 (저는 코딩 스타일이 "콜백 지옥"에 없었습니다).
Mörre

19
ES6에서는 Promise.resolve()"루트 약속"을 만드는 데 사용할 수 없습니까?
zetlen

10
@ MörreNoseshine (계속) 몇 년 후, ES6 저자들이 와서 "이봐, JS 엔진이 일반적인 약속 / A + 준수 유틸리티를 기본 제공해야한다고 명시하자. 그래서 사람들은 항상 기본 약속 도구를 가지고 있어야한다. ". 이것은 매우 편리합니다 (빠른 것 Promise.resolve()또는 무엇이든 하기 위해 라이브러리를 가져올 필요는 없지만) 매우 기본적인 구현이며 그 존재로 인해 블루 버드와 같은 더 심각한 약속 관련 도구를 사용하지 않아도됩니다!
callum

11
비동기 기능이 전혀없는 @ MörreNoseshine 100k LOC Javascript 앱. 블루 버드가없는 mysql / redis 라이브러리로 100k LoC JS 게임을 작성하는 것이 좋습니다.
NiCk Newman 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.