람다 최적화 및 인라인 함수: 컴파일러의 장점
람다가 일반 함수에 비해 우수한 컴파일러 최적화를 보여준다는 Nicolai Josuttis의 진술은 많은 사람들의 흥미를 끌었습니다. 개발자. 이 주장을 조사하면서 우리는 이러한 최적화 이점 뒤에 숨은 근본적인 이유를 밝히려고 합니다.
함수 객체 및 인라인
함수 객체인 람다는 중요한 이점을 가지고 있습니다. 함수 템플릿은 해당 람다에 맞게 특별히 조정된 함수의 인스턴스화를 트리거합니다. 이를 통해 컴파일러는 손쉽게 람다 호출을 인라인할 수 있습니다.
반면, 함수는 함수 템플릿에 전달될 때 함수 포인터를 사용합니다. 전통적으로 컴파일러는 함수 포인터를 통해 호출을 인라인하는 문제에 직면합니다. 인라인 최적화는 둘러싸는 함수 자체가 인라인된 경우에만 가능합니다.
템플릿 인스턴스화: 차이점 탐색
이 차이를 설명하려면 맵 함수 템플릿을 고려하세요.
templatevoid map(Iter begin, Iter end, F f) { for (; begin != end; begin) *begin = f(*begin); }
람다를 사용하여 호출:
int a[] = { 1, 2, 3, 4 }; map(begin(a), end(a), [](int n) { return n * 2; });
는 사용자 정의된 인스턴스화 결과를 가져옵니다.
template void map(int* begin, int* end, _some_lambda_type f) { for (; begin != end; begin) *begin = f.operator()(*begin); }
컴파일러는 _some_lambda_type::operator() 함수를 식별하고 해당 함수에 대한 호출을 직접 인라인할 수 있습니다. 모든 고유한 람다 유형은 지도의 새로운 인스턴스화를 유도하여 람다별 최적화를 보장합니다.
반대로, 함수 포인터로 지도를 호출하면 다음 인스턴스화가 생성됩니다.
template void map(int* begin, int* end, int (*f)(int)) { for (; begin != end; begin) *begin = f(*begin); }
여기서 함수 포인터 f는 각 지도 호출에 대한 다양한 주소를 가리키며 인라인 최적화를 금지합니다. 컴파일러가 f를 특정 함수로 해석하려면 map에 대한 호출이 인라인되어야 합니다.
따라서 함수 객체로서의 람다의 고유성과 템플릿 인스턴스화를 용이하게 하는 능력은 컴파일러에 기존 함수 호출보다 더 뛰어난 최적화 기능을 제공합니다. 포인터를 통해.
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3