JS의 귀속 최적화 - 어디에 있습니까?PTC, TCO 및 FUD
6170 단어 ecmascriptnodewebdevjavascript
kangax의 ES6compat표, 우리는 진도를 검사하는 데 사용되는데, 지금은 모두 녹색일 것입니다. 맞습니까?
응, 그게 아니야.
정확한 꼬리 호출 부분 (꼬리 호출 최적화) 은 빨간색입니다.
왜?이것은 JS를 위해 실현할 수 없는 특성입니까?
없습니다. 브라우저가 이 기능을 실현했습니다.사냥하다.
그리고 이것은 가능하다. 그것은 많은 관중들을 위해 사냥하는 것이다.왜 크롬과 파이어폭스가 뒤떨어질까요?
답안이 복잡하다.내가 훑어본 많은 버그 추적자들이 V8, Firefox JS 엔진,github 문제, TC39위원회 토론 등에 대한 논평을 통해 알 수 있듯이 이 논평들도 매우 정치화되고 자신의 의견을 고집한다.
나는 여기서 이 주제의 배경 지식을 소개해 보려고 한다. 왜 이렇게 어려운지 알려주길 바란다.
PTC?TCO?
PTC-정확한 끝 호출
TCO - 끝 코드 최적화
이 두 용어는 다르다.그들 사이의 차이를 이해하는 것은 뒤의 토론에 매우 중요하다.
앞으로 밀어붙이는 가설
나는 본문을 귀속시키고 창고를 호출하는 입문자로 만들고 싶지 않다.
나는 네가 이미 그 부분을 알고 있다고 생각한다.만약 네가 없다면, freecodecamp 이 방면에 관한 좋은 문장이 한 편 있다.
정확한 꼬리 호출
시작하기 전에, 나는 정확한 꼬리 호출은 ES6에서 이루어져야 하며, 꼬리 코드 최적화가 아니라 ES6에서 이루어져야 한다고 말할 것이다.
그것 ES6 Standard document 중에서 만약 당신이 그것 Formal definitions 을 이해하지 못한다면, 당신은 인용문만 볼 수 있습니다.
Goals for ECMAScript 2015 include providing better support for [...].
Some of its major enhancements include modules, class declarations, [..]
and proper tail calls.
정확한 꼬리 호출은 기술입니다. 프로그램은 꼬리 호출 정의에 부합되는 귀속을 위해 추가 창고 프레임을 만들지 않습니다.이것이 바로 정확한 꼬리 오름세 옵션 가치 주장이다.
따라서, 우리는 1급 창고만 저장하고, 모든 창고를 메모리에 저장하는 것이 아니라, 창고로 돌아가는 것을 최적화할 것이다.
그런데 이게 어떻게 가능하지?꼬리 귀속 함수는 기본적으로 귀속 과정에서 필요한 모든 데이터를 전달하기 때문에 창고에 의존할 필요가 없습니다.
여기서 대표적인 예는 Fibbonaci 함수입니다.
경전(head) 귀속 중 고려:
function factorial(n) {
if (n === 0) {
return 1
}
return n * factorial(n - 1)
}
각 단계의 스택에 의존해야 합니다. 각 단계는 n * factorial(n - 1)
까지 처리해야 하기 때문입니다.현재 이 꼬리 귀속 버전을 고려합니다.
function factorial(n, acc = 1) {
if (n === 0) {
return acc
}
return factorial(n - 1, n * acc)
}
이 버전에서, 우리는 매개 변수로 누적기를 하나 가지고 있다.이것은 지금까지의 총수를 기록했다.따라서 이곳의 창고는 쓸모가 없고 모든 데이터는 귀속 호출에서 사용할 수 있다.너무 좋아요.반복 프로그래밍은 때때로 창고 문제를 호출하지 않은 교체 방안보다 파악하기 쉽다.그것들은 기본적으로 등가이다!
다만, 그들은 아니다.PTC의 경우에는 사용할 수 없습니다.
PTC의 문제는 described beautifully 최근 Ecmascript에서 제시된 TCO 제안입니다.
기본적으로 다음과 같습니다.
디버깅 문제는 거래를 파괴하고 성능 문제는 분석을 말살한다고 한다.다른 사람들은 이것이 FUD라고 생각한다. 왜냐하면 사파리가 PTC를 실현했기 때문에 지옥은 여전히 닫혀 있다.
당신은 이곳에서 성인들이 그들의 신앙을 위해 격렬하게 투쟁하는 것을 찾을 수 있습니다.
https://github.com/tc39/proposal-ptc-syntax/issues/23
https://bugs.chromium.org/p/v8/issues/detail?id=4698
끝부분 호출 최적화
꼬리 호출 최적화 구조!
응, 사실은 아니지만, 나는 극화되고 싶어.
꼬리 코드 최적화의 차이점은 추가 창고 호출을 제거할 뿐만 아니라 귀속 함수를 교체 함수로 완전히 다시 컴파일하는 데 있다.
백그라운드에서 꼬리 코드 최적화는 귀속 함수를 사용하고 내부에서
goto
를 사용하여 교체 함수를 생성한 다음에 실행합니다.함수가 실제로 백그라운드에서 귀속되지 않으면 창고 호출이 없기 때문에 창고 호출을 제한하지 않습니다.
이것은 성능 문제를 완벽하게 해결했다.
Lua actually has this implemented long ago, 그것은 아주 잘 일한다.귀속 함수의 성능은 등가의 교체 함수와 같다.
네, 그럼 왜 TCO를 실시하지 않습니까?
좋아요.이 점에 관해서도 많은 논쟁이 있다.
'스텔스'총소유비용을 원하는 사람이 있다. 즉, 꼬리 부분에 최적화된 함수를 식별할 때 적당한 곳에서만 실행하면 된다는 것이다.
개발자가 의도한 경우에만 이렇게 하는 명확한 TCO를 원하는 사람도 있다.
이것이 바로 current proposal for Syntactic Tail Calls의 전체 내용이다.
이것은 끝부분 호출 최적화를 위해 새로운 문법과 새로운 키워드, 즉
continue
키워드를 도입했다.그리고 여기서도 논란이 많은 것 같다.
물론 나는 세부 사항을 깊이 있게 토론하지 않았지만, 나는 이것이 왜 이 주제가 복잡하고 정확하게 이해하기 어려운지 기본적으로 이해할 수 있을 것이라고 생각한다.
여느 때와 마찬가지로 이 주제와 Ecmascript 제안에서 일하는 모든 분들께 감사드립니다.너의 일과 열정에 대한 충분한 토론은 결국 우리 모두에게 유익하다.
Reference
이 문제에 관하여(JS의 귀속 최적화 - 어디에 있습니까?PTC, TCO 및 FUD), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/snird/recursion-optimization-in-js-where-is-it-ptc-tco-and-fud-4fka텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)