λ -calculus : 함수의 메모리 표현에서 가장 효율적인 것은 무엇입니까?


9

함수 인코딩 (Church 's / Scott 's)과 클래식 인코딩 (어셈블러 / C) 데이터 구조의 성능을 비교하고 싶습니다.

그러나 그렇게하기 전에 메모리에서 함수 표현이 얼마나 효율적인지 알아야합니다. 이 기능은 물론 부분적으로 적용될 수 있습니다 (일명 폐쇄).

현재 인코딩 알고리즘의 인기있는 기능 언어 (Haskell, ML) 사용 달성 할 수있는 가장 효율적인 언어에 관심 이 있습니다.


보너스 포인트 :이지도는 기본 정수로 정수를 인코딩 기능하도록 인코딩 (인가 short, int등 C에서). 가능합니까?


나는 성능을 기준으로 효율성을 중시합니다. 다시 말해, 인코딩이 효율적 일수록 기능적인 데이터 구조로 계산 성능에 영향을 덜 미칩니다.


Google의 모든 시도가 실패했습니다. 올바른 키워드를 모르는 것 같습니다.
포드 O.

"효율적인"의 의미를 명확히하기 위해 질문을 편집 할 수 있습니까? 무엇을 위해 효율적입니까? 효율적인 데이터 구조를 요구할 때는 데이터 구조의 선택에 영향을 미치므로 데이터 구조에 대해 수행 할 수있는 작업을 지정해야합니다. 아니면 인코딩이 가능한 한 공간 효율적이라는 것을 의미합니까?
DW

1
이것은 상당히 광범위합니다. 효율적으로 실행하는 것을 목표로하는 람다 미적분학을위한 추상 머신이 많이 있습니다 (예 : SECD, CAM, Krivine 's, STG 참조). 또한 더 많은 문제가있는 Church / Scott 인코딩 데이터를 고려해야합니다. 예를 들어 Church 인코딩 목록에서 테일 연산은 O (1) 대신 O (n)이어야합니다. O (1) 헤드 및 테일 연산을 사용하는 시스템 F의 목록에 대한 인코딩이 여전히 공개 된 문제라고 생각합니다.
chi

@DW 성능 / 오버 헤드에 대해 이야기하고 있습니다. 예를 들어 교회 목록과 하스켈 목록에 대한 효율적인 인코딩 매핑의 경우 같은 시간이 걸립니다.
포드 O.

어떤 작업에 대한 성능? 기능으로 무엇을하고 싶습니까? 이 기능들을 어떤 가치로 평가하고 싶습니까? 한 번 또는 여러 값에서 동일한 기능을 평가합니까? 그들과 다른 일을합니까? 함수 (함수 언어로 작성)를 컴파일하여 가능한 한 효율적으로 실행할 수있는 방법을 묻고 있습니까?
DW

답변:


11

문제는 함수 인코딩 측면에서 실제로 많은 여유가 없다는 것입니다. 주요 옵션은 다음과 같습니다.

  • 용어 재 작성 : 함수를 추상 구문 트리 (또는 그 일부 인코딩)로 저장합니다. 함수를 호출 할 때 구문 트리를 수동으로 이동하여 매개 변수를 인수로 대체합니다. .

  • 클로저 : 함수를 표현하는 방법, 구문 트리, 기계 코드 일 가능성이 있습니다. 그리고이 함수들에서, 당신은 어떤 식 으로든 당신의 주장을 참조로 참조합니다. 포인터 오프셋 일 수 있고 정수 또는 De Bruijn 색인 일 수 있으며 이름 일 수 있습니다. 그런 다음 함수를 클로저 로 표시합니다. 함수의 모든 자유 변수를 포함하는 데이터 구조와 쌍을 이루는 함수 "명령"(트리, 코드 등)입니다. 함수가 실제로 적용되면 어떻게 든 환경, 포인터 산술 등을 사용하여 데이터 구조에서 자유 변수를 찾는 방법을 알 수 있습니다.

다른 옵션이 있다고 확신하지만 이것이 기본 옵션이며 거의 모든 다른 옵션이 기본 폐쇄 구조의 변형 또는 최적화가 될 것으로 생각합니다.

따라서 성능 측면에서 클로저는 용어 재 작성보다 거의 보편적으로 성능이 우수합니다. 변형 중 어떤 것이 더 낫습니까? 그것은 당신의 언어와 아키텍처에 크게 의존하지만 "무료 변수를 포함하는 구조체가있는 기계 코드"가 가장 효율적이라고 생각합니다. 그것은 함수가 필요로하는 모든 것 (지시와 값)을 가지고 있으며, 더 이상 아무것도 호출하지 않으며, 장기 호출을 끝내지 않습니다.

현재 인코딩 알고리즘의 인기있는 기능 언어 (Haskell, ML) 사용에 관심이 있습니다.

나는 전문가는 아니지만 99 %의 ML 맛이 있지만 일부 최적화는 가능하지만 설명하는 클로저의 변형을 사용합니다. (아마도 구식 일 수도 있음) 관점에 대해서는 내용을 참조하십시오 .

Haskell은 게으른 평가로 인해 조금 더 복잡한 작업을 수행합니다. Spineless Tagless Graph Rewriting을 사용 합니다.

또한 가장 효율적인 방법으로 달성 할 수 있습니다.

가장 효율적인 것은 무엇입니까? 모든 입력에서 가장 효율적인 구현은 없으므로 평균적으로 효율적인 구현을 얻을 수 있지만 각각 다른 시나리오에서 우수합니다. 따라서 가장 효율적이거나 가장 효율이 낮은 명확한 순위는 없습니다.

여기 마법이 없습니다. 함수를 저장하려면 자유 값을 어떻게 든 저장 해야 합니다. 그렇지 않으면 함수 자체보다 적은 정보를 인코딩합니다. 부분 평가를 통해 일부 무료 값을 최적화 할 수 있지만 성능이 위험 할 수 있으므로 항상 중지되도록주의해야합니다.

공간 효율성을 얻기 위해 일종의 압축 또는 영리한 알고리즘을 사용할 수 있습니다. 그러나 당신은 우주를 위해 거래하는 시간이거나 어떤 경우에 최적화되어 있고 다른 경우에는 느려지는 상황에 처해 있습니다.

일반적인 경우는 최적화 할 수 있지만 일반적인 경우 언어, 응용 프로그램 영역 등에서 변경 될 수 있습니다. 비디오 게임에 빠른 코드 유형 (숫자 크 런칭, 큰 입력의 타이트한 루프)은 아마도 컴파일러 (트리 탐색, 작업 목록 등)의 빠른 속도

보너스 포인트 : 함수 인코딩 된 정수를 네이티브 정수 (C의 short, int 등)에 매핑하는 인코딩이 있습니까? 가능합니까?

아니요, 불가능합니다. 문제는 람다 미적분이 용어를 내성적으로 만들 수 없다는 것입니다. 함수가 Church-numeral과 동일한 유형의 인수를 사용하는 경우 해당 숫자의 정확한 정의를 검사하지 않고 함수를 호출 할 수 있어야합니다. 이것이 교회 인코딩의 일입니다. 당신이 그들과 함께 할 수 있는 유일한 것은 그것들을 부르는 것입니다. 그리고 당신은 이것으로 유용한 모든 것을 시뮬레이션 할 수 있지만 비용이 없습니다.

더 중요한 것은 정수는 가능한 모든 이진 인코딩을 차지한다는 것입니다. 따라서 람다가 정수로 표시되면 교회 수가 아닌 람다를 나타낼 방법이 없습니다! 또는 람다가 숫자인지 여부를 나타내는 플래그를 소개하지만 원하는 효율성은 아마도 창 밖으로 나옵니다.

편집 : 이것을 작성 한 후, 고기능 함수를 구현하기위한 세 번째 옵션 인 defunctionalization을 알게되었습니다 . 여기서는 함수 switch로 제공된 람다 추상화에 따라 모든 함수 호출이 큰 문장 으로 바뀝니다 . 여기서의 단점은 전체 프로그램 변환이라는 것입니다. 사전에 완전한 람다 추상화 세트가 필요하기 때문에 부분을 개별적으로 컴파일 한 다음이 방식으로 연결할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.