[Final] PEP 523 - Adding a frame evaluation API to CPython
원문 링크: PEP 523 - Adding a frame evaluation API to CPython
상태: Final 유형: Standards Track 작성일: 16-May-2016
PEP 523 – CPython에 프레임 평가 API 추가
개요 (Abstract)
이 PEP는 CPython의 C API를 확장하여 인터프리터별 프레임 평가 함수를 지정할 수 있도록 제안합니다. 또한, 이 제안은 프레임 평가 함수에서 사용할 임의의 데이터를 저장하기 위해 코드 객체에 새로운 필드를 추가하는 것을 포함합니다.
배경 (Rationale)
Python 코드의 직접적인 실행에는 유연성이 부족한 부분이 있었습니다. CPython의 C API는 프레임 객체에 데이터를 구성하고 PyEval_EvalFrameEx()
를 통해 평가할 수 있도록 허용하지만, Python 코드 실행에 대한 제어는 프레임 수준의 전체적인 제어가 아닌 개별 객체에만 국한되었습니다.
프레임 평가에 대한 영향을 원한다는 것이 다소 로우레벨(low-level)하게 들릴 수 있지만, 이는 CPython 자체에서 제공할 필요 없이 메서드 수준의 JIT (Just-In-Time Compiler)를 CPython에 도입할 가능성을 열어줍니다. 외부 C 코드가 프레임 평가를 제어할 수 있도록 함으로써, JIT는 평가가 발생하는 핵심 지점에서 Python 코드 실행에 참여할 수 있습니다. 이를 통해 JIT는 필요에 따라 Python 바이트코드를 머신 코드로 조건부 재컴파일할 수 있으며, JIT 실행이 원치 않을 때는 일반 CPython 바이트코드를 실행할 수 있습니다. 이는 인터프리터가 프레임을 평가하기 위해 호출할 함수를 지정할 수 있도록 함으로써 달성됩니다. 또한, API를 프레임 평가 수준에 배치함으로써 JIT가 코드의 실행 환경에 대한 완전한 시야를 가질 수 있습니다.
프레임 평가 함수를 지정하는 이러한 기능은 CPython을 JIT에 개방하는 것 외에도 다른 사용 사례를 가능하게 합니다. 예를 들어, 이 API를 사용하면 호출 수준에서 트레이싱(tracing) 또는 프로파일링(profiling) 기능을 구현하는 것이 어렵지 않을 것입니다. CPython은 Python 수준에서 트레이싱 또는 프로파일링 함수를 설정하는 기능을 제공하지만, 이 API는 프로파일러의 데이터 수집과 일치할 수 있으며, 라인별 트레이싱 지원을 단순히 건너뛰어 트레이싱에 더 빠를 수 있습니다.
또한, 이는 디버깅(debugging)의 가능성을 열어줍니다. 프레임 평가 함수는 특정 코드 객체를 실행하려고 할 때만 특별한 디버깅 작업을 수행할 수 있습니다. 이 경우, 바이트코드는 이론적으로 인플레이스(in-place)로 재작성되어 적절한 지점에 브레이크포인트(breakpoint) 함수 호출을 삽입하여 디버깅을 돕고, sys.settrace()
에서 요구하는 강력한 접근 방식을 사용하지 않을 수 있습니다.
이러한 사용 사례를 용이하게 하기 위해, 새로운 필드를 통해 코드 객체에 “스크래치 공간(scratch space)”을 추가하는 것도 제안됩니다. 이를 통해 코드 객체별 데이터를 코드 객체 자체에 저장하여, 필요에 따라 프레임 평가 함수가 쉽게 검색할 수 있도록 합니다. 필드 자체는 단순히 PyObject *
타입이므로, 필드에 저장된 모든 데이터는 일반 객체 메모리 관리(object memory management)에 참여하게 됩니다.
제안 (Proposal)
아래 제안된 모든 C API 변경 사항은 안정적인 ABI (Application Binary Interface)의 일부가 되지 않습니다.
PyCodeObject
확장
PyCodeObject
구조체에 하나의 필드가 추가됩니다.
typedef struct {
/* ... */
void *co_extra; /* "Scratch space" for the code object. */
} PyCodeObject;
co_extra
는 기본적으로 NULL
이며 필요에 따라 채워집니다. 필드에 저장된 값은 코드 객체가 작동하는 데 필수는 아니므로, 데이터 손실이 허용됩니다.
이 필드와 함께 작동하기 위해 비공개(private) API가 도입되었습니다.
PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra);
PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra);
필드 사용자는 _PyEval_RequestCodeExtraIndex()
를 호출하여 co_extra
에 데이터를 추가할 불투명한 인덱스(opaque index) 값을 받아야 합니다. 이 인덱스를 사용하여 사용자는 _PyCode_SetExtra()
로 데이터를 설정하고 나중에 _PyCode_GetExtra()
로 데이터를 검색할 수 있습니다. 이 API는 Python 릴리스 간에 API의 의미론적 보장(semantic guarantees)이 없음을 알리기 위해 의도적으로 비공개로 나열되었습니다.
리스트(list)와 튜플(tuple) 사용이 고려되었지만 성능이 떨어지는 것으로 나타났으며, 주요 사용 사례가 JIT인 점을 고려할 때 Python 객체 대신 사용자 정의 구조체를 사용하는 것이 성능 면에서 우세했습니다. 딕셔너리(dict)도 고려되었지만, 다시 한번 성능이 더 중요했습니다. 딕셔너리는 데이터 조회에 상수 오버헤드(constant overhead)가 있지만, 데이터 구조에 단일 객체가 저장되는 일반적인 경우에 튜플이 더 나은 성능 특성을 가집니다 (예: 길이가 1인 튜플을 반복하는 것이 딕셔너리에서 객체를 해싱하고 조회하는 오버헤드보다 빠릅니다).
PyInterpreterState
확장
프레임 평가 함수의 진입점은 인터프리터별(per-interpreter)입니다.
// PyEval_EvalFrameEx()와 동일한 타입 시그니처(type signature)입니다.
typedef PyObject* (*_PyFrameEvalFunction)(PyFrameObject*, int);
typedef struct {
/* ... */
_PyFrameEvalFunction eval_frame;
} PyInterpreterState;
기본적으로 eval_frame
필드는 현재 PyEval_EvalFrameEx()
가 나타내는 함수 포인터(이 PEP에서 나중에 논의되는 _PyEval_EvalFrameDefault()
라고 불림)로 초기화됩니다. 타사 코드(third-party code)는 Python 코드의 실행을 제어하기 위해 자체 프레임 평가 함수를 설정할 수 있습니다. 포인터 비교를 사용하여 필드가 _PyEval_EvalFrameDefault()
로 설정되었는지, 따라서 아직 변경되지 않았는지 감지할 수 있습니다.
Python/ceval.c
변경 사항
현재 PyEval_EvalFrameEx()
는 _PyEval_EvalFrameDefault()
로 이름이 변경됩니다. 새로운 PyEval_EvalFrameEx()
는 다음과 같아집니다.
PyObject *
PyEval_EvalFrameEx(PyFrameObject *frame, int throwflag)
{
PyThreadState *tstate = PyThreadState_GET();
return tstate->interp->eval_frame(frame, throwflag);
}
이는 타사 코드가 기존 C API를 이미 사용하는 코드와의 하위 호환성(backwards-compatible)을 유지하면서 Python 코드 실행 경로에 직접 자신을 배치할 수 있도록 합니다.
python-gdb.py
업데이트
GDB에서 Python 지원을 위해 사용되는 생성된 python-gdb.py
파일은 PyEval_EvalFrameEx()
에 대해 일부 하드코딩된 가정(예: 지역 변수 이름)을 합니다. 제안된 변경 사항과 함께 작동하도록 업데이트해야 합니다.
성능 영향 (Performance impact)
이 PEP는 플러그인 기능(pluggability)을 추가하기 위한 API를 제안하므로, 성능 영향은 타사 코드가 아무런 변경을 하지 않은 경우에만 고려됩니다.
pybench
의 여러 실행에서 API 변경만으로는 일관되게 성능 저하가 없음을 보여주었습니다.
Python 벤치마크 스위트의 실행에서는 측정 가능한 성능 비용이 없었습니다.
메모리 영향 측면에서, 단일 프로세스에서 실행되는 CPython 인터프리터가 일반적으로 많지 않으므로 PyCodeObject
에 co_extra
가 추가되는 영향만 우려됩니다.에 따르면, Python 테스트 스위트의 실행 결과 약 72,395개의 코드 객체가 생성됩니다. 64비트 CPU에서 모든 코드 객체가 동시에 활성 상태이고 co_extra
필드에 아무것도 설정되지 않은 경우, 579,160바이트의 추가 메모리가 사용될 것입니다.
예시 사용 (Example Usage)
CPython용 JIT (A JIT for CPython)
Pyjion
Pyjion 프로젝트는 이 제안된 API를 사용하여 CoreCLR의 JIT를 활용하여 CPython용 JIT를 구현했습니다. 각 코드 객체는 co_extra
필드가 PyjionJittedCode
객체로 설정되며, 이 객체는 네 가지 정보를 저장합니다.
- 실행 횟수 (Execution count)
- 이전 JIT 시도가 실패했는지 여부를 나타내는 부울(boolean) 값
- 트램폴린(trampoline)에 대한 함수 포인터 (타입 트레이싱 여부와 관계없이)
- JIT 컴파일된 머신 코드에 대한
void
포인터
프레임 평가 함수는 (대략적으로) 다음과 같은 알고리즘을 가집니다.
def eval_frame(frame, throw_flag):
pyjion_code = frame.code.co_extra
if not pyjion_code:
frame.code.co_extra = PyjionJittedCode()
elif not pyjion_code.jit_failed:
if not pyjion_code.jit_code:
return pyjion_code.eval(pyjion_code.jit_code, frame)
elif pyjion_code.exec_count > 20_000:
if jit_compile(frame):
return pyjion_code.eval(pyjion_code.jit_code, frame)
else:
pyjion_code.jit_failed = True
pyjion_code.exec_count += 1
return _PyEval_EvalFrameDefault(frame, throw_flag)
핵심은 이 모든 작업과 로직이 CPython과 분리되어 있지만, 제안된 API 변경 사항 덕분에 Python 시맨틱(semantics)을 준수하는 JIT를 제공할 수 있다는 것입니다 (이 글을 쓰는 시점에는 새로운 API가 없는 CPython과 성능이 거의 동일합니다). 이는 제안된 API를 활용하여 다른 사람들이 CPython용 자체 JIT를 구현하는 것을 기술적으로 막는 것이 없음을 의미합니다.
다른 JIT (Other JITs)
Pyston 팀은 이 PEP의 초기 버전에 대해 자문을 받았는데, 그 버전은 JIT에 더 특화되어 있었고, 그들은 메모리 레이아웃에 대한 제어를 원했기 때문에 제안된 변경 사항을 활용하는 데 관심이 없었습니다. PyPy 팀의 개발자와의 비공식적인 논의에서도 비슷한 의견이 나왔습니다.
반면 Numba는 1.0 이후의 미래에 제안된 변경 사항에 관심이 있을 것이라고 제안했습니다.
실험적인 Coconut JIT는 이 PEP의 혜택을 받을 수 있었습니다. Coconut의 개발자와의 비공개 대화에서, 우리의 API가 CPython에 JIT 지원을 추가하기 위해 그들이 개발한 API보다 아마도 우수할 것이라는 말을 들었습니다.
디버깅 (Debugging)
Python Tools for Visual Studio (PTVS) 팀과의 대화에서, 그들은 이 API 변경 사항이 더 나은 성능의 디버깅을 구현하는 데 유용할 것이라고 생각했습니다. 배경 섹션에서 언급했듯이, 이 API는 디버깅 기능이 필요한 프레임에서만 전환될 수 있도록 합니다. 이는 sys.settrace()
가 일반적으로 제공하는 정보를 건너뛰는 것을 허용하고, 심지어 실행 전에 바이트코드를 동적으로 재작성하여 바이트코드에 브레이크포인트를 주입하는 것까지 가능하게 합니다.
Google도 내부적으로 매우 유사한 API를 제공하며, 이는 성능이 뛰어난 디버깅 목적으로 사용되었습니다.
구현 (Implementation)
제안된 API를 구현하는 일련의 패치는 Pyjion 프로젝트를 통해 제공됩니다. 현재 형태로 이 제안된 API보다 CPython에 더 많은 변경 사항이 있지만, 이는 엄격한 목표 달성 요구 사항 대신 개발의 용이성을 위한 것입니다.
미해결 문제 (Open Issues)
eval_frame
을 NULL
로 허용할 것인가? (Allow eval_frame to be NULL)
현재 프레임 평가 함수는 항상 설정되어 있어야 합니다. 단순히 기본적으로 NULL
로 설정하여 _PyEval_EvalFrameDefault()
를 사용하도록 신호를 보낼 수도 있습니다. 필드를 특별히 처리하지 않는 현재 제안이 가장 간단해 보였지만, 필드가 실수로 지워지지 않도록 해야 하며, 그렇지 않으면 충돌(crash)이 발생할 수 있습니다.
기각된 아이디어 (Rejected Ideas)
JIT-특정 C API (A JIT-specific C API)
원래 이 PEP는 JIT에 더 특화된 훨씬 더 큰 API 변경을 제안하려고 했습니다. 그러나 Numba 팀으로부터 피드백을 받은 후, API가 불필요하게 크다는 것이 분명해졌습니다. 진정으로 필요한 것은 JIT 컴파일된 Python 코드의 실행을 처리할 트램폴린 함수를 제공할 기회와, 컴파일된 머신 코드를 다른 중요한 데이터와 함께 해당 Python 코드 객체에 연결하는 방법이라는 것을 깨달았습니다. 필요한 API 변경을 최소화하면서 기능이나 성능 손실이 없다는 것이 입증된 후, 제안은 현재 형태로 변경되었습니다.
co_extra
가 필요한가? (Is co_extra needed?)
PyCon US 2016에서 이 PEP를 논의하는 동안, 일부 핵심 개발자들은 co_extra
필드가 코드 객체를 변경 가능하게 만들 수 있다는 우려를 표했습니다. 코드 객체가 생성된 후 변경되는 필드를 갖는 것이 객체를 변경 가능하게 보이게 한다는 생각이었지만, 코드 객체의 다른 측면은 변경되지 않았습니다.
이 PEP의 관점은 co_extra
필드가 코드 객체가 불변(immutable)이라는 사실을 바꾸지 않는다는 것입니다. 이 필드는 코드 객체를 사용할 수 있게 만드는 데 필요한 정보를 포함하지 않도록 이 PEP에서 지정되었으므로, 캐싱 필드에 가깝습니다. 이는 문자열 객체가 내부적으로 가지는 UTF-8 캐시와 유사하게 볼 수 있습니다. 문자열은 조건부로 설정되는 필드를 가지고 있음에도 불구하고 여전히 불변으로 간주됩니다.
JIT 워크로드에서 필드를 사용할 수 없을 때도 성능 측정이 이루어졌습니다. C++의 정렬되지 않은 맵(unordered map) 또는 Python의 딕셔너리를 사용하여 코드 객체를 JIT-특정 데이터 객체와 연결할 때 필드의 손실은 성능에 너무 큰 비용을 초래하는 것으로 간주되었습니다.
참고 자료 (References)
- Pyjion 프로젝트 (https://github.com/microsoft/pyjion)
- CPython의 C API (https://docs.python.org/3/c-api/index.html)
- PyCodeObject (https://docs.python.org/3/c-api/code.html#c.PyCodeObject)
- .NET Core Runtime (CoreCLR) (https://github.com/dotnet/coreclr)
- PyEval_EvalFrameEx() (https://docs.python.org/3/c-api/veryhigh.html?highlight=pyframeobject#c.PyEval_EvalFrameEx)
- Numba (http://numba.pydata.org/)
- numba-users 메일링 리스트: “Would the C API for a JIT entrypoint being proposed by Pyjion help out Numba?” (https://groups.google.com/a/continuum.io/forum/#!topic/numba-users/yRl_0t8-m1g)
- [Python-Dev] Opcode cache in ceval loop (https://mail.python.org/pipermail/python-dev/2016-February/143025.html)
- Python 벤치마크 스위트 (https://hg.python.org/benchmarks)
- Pyston (http://pyston.org)
- PyPy (http://pypy.org/)
- Python Tools for Visual Studio (http://microsoft.github.io/PTVS/)
- Coconut (https://github.com/davidmalcolm/coconut)
- pybench (https://hg.python.org/cpython/file/default/Tools/pybench)
저작권 (Copyright)
이 문서는 퍼블릭 도메인에 공개되었습니다.
Source: https://github.com/python/peps/blob/main/peps/pep-0523.rst
최종 수정: 2025-02-01 08:55:40 GMTPEP 523은 CPython의 C API를 확장하여 프레임 평가 함수를 지정할 수 있도록 하는 제안입니다. 이 문서는 Python 개발자들이 JIT 컴파일러, 고급 디버깅 도구, 그리고 프로파일링 도구와 같은 외부 도구들이 CPython의 실행 흐름에 더 깊이 개입할 수 있도록 하는 것을 목표로 합니다.
PEP 523 – CPython에 프레임 평가 API 추가
개요 (Abstract)
이 PEP는 CPython의 C API를 확장하여 인터프리터별 프레임 평가 함수를 지정할 수 있도록 제안합니다. 또한, 이 제안은 프레임 평가 함수에서 사용할 임의의 데이터를 저장하기 위해 코드 객체 (code object)에 새로운 필드를 추가하는 것을 포함합니다.
배경 (Rationale)
기존 CPython은 PyEval_EvalFrameEx()
를 통해 프레임을 평가하는 기능을 제공했지만, Python 코드 실행에 대한 전체적인 제어보다는 개별 객체 수준에서의 제어에 머물러 있었습니다. 이러한 유연성 부족은 특히 JIT(Just-In-Time) 컴파일러와 같은 외부 도구가 CPython의 실행 흐름에 통합되는 것을 어렵게 했습니다.
이 PEP는 프레임 수준에서 실행 제어를 제공함으로써 다음과 같은 가능성을 열어줍니다:
- JIT 컴파일러 도입: CPython 자체에 JIT를 내장하지 않고도, 외부 C 코드가 프레임 평가를 제어하여 Python 바이트코드를 머신 코드로 조건부 재컴파일할 수 있도록 합니다. 이는 JIT가 필요한 경우에만 활성화되고, 그렇지 않은 경우에는 표준 CPython 바이트코드를 실행할 수 있게 합니다.
- 고급 트레이싱 및 프로파일링: 호출 수준에서 트레이싱 또는 프로파일링 기능을 더 효율적으로 구현할 수 있게 됩니다.
sys.settrace()
와 같은 기존 Python 수준의 기능보다 더 빠르고 상세한 데이터 수집이 가능하며, 라인별 트레이싱을 건너뛰는 등의 최적화도 가능합니다. - 효율적인 디버깅: 프레임 평가 함수가 특정 코드 객체를 실행하기 전에 디버깅 작업을 수행할 수 있도록 합니다. 이는 바이트코드를 동적으로 재작성하여 브레이크포인트(breakpoint)를 삽입하는 등의 고급 디버깅 기능을
sys.settrace()
보다 가벼운 방식으로 구현할 수 있게 합니다.
이러한 사용 사례를 지원하기 위해, 코드 객체에 새로운 “스크래치 공간(scratch space)” 필드인 co_extra
를 추가하는 것도 제안됩니다. 이 필드는 프레임 평가 함수가 필요에 따라 코드 객체별 데이터를 저장하고 검색하는 데 사용됩니다.
제안 (Proposal)
제안된 C API 변경 사항은 안정적인 ABI (Application Binary Interface)의 일부가 되지 않습니다.
PyCodeObject
확장
PyCodeObject
구조체에 void *co_extra;
필드가 추가됩니다.
co_extra
는 기본적으로NULL
이며, 필요에 따라 임의의 데이터를 저장하는 데 사용됩니다.- 이 필드에 저장된 데이터는 코드 객체 기능에 필수는 아니므로, 데이터 손실이 허용됩니다.
co_extra
와 상호작용하기 위한 비공개 API인_PyEval_RequestCodeExtraIndex()
,_PyCode_GetExtra()
,_PyCode_SetExtra()
가 제공됩니다. 이 API는 Python 릴리스 간에 의미론적 보장이 없으므로 주의해야 합니다. 성능상의 이유로 리스트, 튜플, 딕셔너리 대신 사용자 정의 구조체와 유사한 방식으로 관리됩니다.
PyInterpreterState
확장
인터프리터별(per-interpreter) 프레임 평가 함수를 위한 진입점이 추가됩니다.
PyInterpreterState
구조체에_PyFrameEvalFunction eval_frame;
필드가 추가됩니다.eval_frame
은 기본적으로 기존PyEval_EvalFrameEx()
의 동작을 나타내는_PyEval_EvalFrameDefault()
함수 포인터로 초기화됩니다.- 타사 코드는 이
eval_frame
필드를 자신의 커스텀 함수로 설정하여 Python 코드 실행을 제어할 수 있습니다.
Python/ceval.c
변경 사항
- 기존
PyEval_EvalFrameEx()
는_PyEval_EvalFrameDefault()
로 이름이 변경됩니다. - 새로운
PyEval_EvalFrameEx()
는PyThreadState *tstate = PyThreadState_GET(); return tstate->interp->eval_frame(frame, throwflag);
와 같이 현재 스레드의 인터프리터에 설정된eval_frame
함수를 호출하도록 변경됩니다. - 이 변경은 타사 코드가 Python 코드 실행 경로에 직접 개입하면서도 기존 C API를 사용하는 코드와의 하위 호환성(backwards-compatible)을 유지하도록 합니다.
python-gdb.py
업데이트
GDB의 Python 지원을 위한 python-gdb.py
파일은 PyEval_EvalFrameEx()
에 대한 가정을 포함하므로, 제안된 변경 사항과 호환되도록 업데이트되어야 합니다.
성능 영향 (Performance impact)
이 PEP는 플러그인 기능(pluggability)을 위한 API를 제안하므로, 타사 코드가 변경을 가하지 않은 경우의 성능 영향만 고려됩니다.
pybench
및 Python 벤치마크 스위트 실행 결과, API 변경만으로는 측정 가능한 성능 저하가 없었습니다.- 메모리 측면에서는
co_extra
필드가PyCodeObject
에 추가됨으로써 발생할 수 있는 영향이 우려됩니다. 약 72,395개의 코드 객체가 생성되는 Python 테스트 스위트 실행 기준으로, 64비트 CPU에서 최대 579,160바이트의 추가 메모리 사용이 발생할 수 있습니다.
예시 사용 (Example Usage)
CPython용 JIT (A JIT for CPython)
- Pyjion: 이 제안된 API를 사용하여 CoreCLR의 JIT를 활용한 CPython용 JIT를 구현했습니다.
co_extra
필드에 JIT 컴파일된 코드와 관련 메타데이터를 저장하고,eval_frame
함수를 오버라이드하여 JIT 컴파일된 코드를 실행합니다. 이는 CPython과 분리된 상태로 Python 시맨틱을 준수하는 JIT를 제공하는 것이 가능함을 보여줍니다. - 다른 JITs: Pyston 및 PyPy 팀은 초기 버전의 PEP에 큰 관심을 보이지 않았으나, Numba는 향후 버전에 관심을 표명했습니다. Coconut JIT 또한 이 PEP의 혜택을 받을 수 있었을 것입니다.
디버깅 (Debugging)
- Python Tools for Visual Studio (PTVS) 팀은 이 API가 더 높은 성능의 디버깅 기능을 구현하는 데 유용할 것이라고 언급했습니다. 필요한 프레임에서만 디버깅 기능을 활성화하고, 바이트코드를 동적으로 재작성하여 브레이크포인트를 주입하는 등의 고급 기능을 구현할 수 있습니다. Google도 내부적으로 유사한 API를 사용하여 성능 좋은 디버깅에 활용하고 있습니다.
구현 (Implementation)
제안된 API를 구현하는 패치 세트는 Pyjion 프로젝트를 통해 제공됩니다.
미해결 문제 (Open Issues)
eval_frame
을NULL
로 허용할 것인가?: 현재는eval_frame
이 항상 설정되어 있어야 하지만,NULL
을 기본값으로 하여_PyEval_EvalFrameDefault()
를 사용하도록 신호를 보낼 수도 있습니다. 필드가 우발적으로 지워져 충돌이 발생하는 것을 방지해야 합니다.
기각된 아이디어 (Rejected Ideas)
JIT-특정 C API (A JIT-specific C API)
초기에는 더 크고 JIT에 특화된 API가 제안되었으나, Numba 팀의 피드백을 통해 불필요하게 크다는 것이 밝혀졌습니다. 결국, JIT 컴파일된 Python 코드 실행을 처리할 트램폴린 함수와 컴파일된 코드를 Python 코드 객체에 연결하는 방법만 있으면 된다는 결론에 도달하여 현재의 간소화된 형태로 변경되었습니다.
co_extra
가 필요한가? (Is co_extra needed?)
co_extra
필드가 코드 객체를 변경 가능하게 만들 수 있다는 우려가 제기되었습니다. 그러나 이 PEP는 co_extra
필드가 코드 객체 자체의 불변성(immutability)을 변경하지 않으며, 코드 객체가 작동하는 데 필요한 정보를 포함하지 않고 주로 캐싱(caching) 목적으로 사용된다고 주장합니다. 이는 문자열 객체의 내부 UTF-8 캐시와 유사하게 볼 수 있습니다. 성능 측정 결과, JIT 워크로드에서 이 필드가 없을 경우 성능 저하가 너무 커서 필드를 유지하는 것이 합당하다고 판단되었습니다.
참고 자료 (References)
문서 말미에 언급된 다양한 프로젝트, API 문서, 메일링 리스트 및 벤치마크 도구에 대한 참고 자료가 포함되어 있습니다.
⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.
Comments