좋아하는 컴파일러에 질문하지 않으시겠습니까?간단한을 위해 제공
~/projects$ clang++ -O2 -c -I/usr/lib/Boost/1-39-0-1/include/ test.cpp -emit-llvm
~/projects$ llvm-dis test.o -show-annotations
: 우리는 LLVM IR 검색이 명령으로
#include <cstring>
#include <cstdio>
#include <boost/foreach.hpp>
char const* HelloWorld = "Hello, world!\n";
void simplefor() {
for(char const* it = HelloWorld, *end = HelloWorld + strlen(HelloWorld);
it != end;
++it)
{
printf("%c", *it);
}
}
void foreach() {
BOOST_FOREACH(char ch, HelloWorld)
{
printf("%c", ch);
}
}
:
define void @_Z9simpleforv() nounwind uwtable {
%1 = load i8** @HelloWorld, align 8, !tbaa !0 ; [#uses=3 type=i8*]
%2 = tail call i64 @strlen(i8* %1) nounwind readonly ; [#uses=2 type=i64]
%3 = getelementptr inbounds i8* %1, i64 %2 ; [#uses=1 type=i8*]
%4 = icmp eq i64 %2, 0 ; [#uses=1 type=i1]
br i1 %4, label %._crit_edge, label %.lr.ph
.lr.ph: ; preds = %.lr.ph, %0
%it.01 = phi i8* [ %7, %.lr.ph ], [ %1, %0 ] ; [#uses=2 type=i8*]
%5 = load i8* %it.01, align 1, !tbaa !1 ; [#uses=1 type=i8]
%6 = sext i8 %5 to i32 ; [#uses=1 type=i32]
%putchar = tail call i32 @putchar(i32 %6) nounwind ; [#uses=0 type=i32]
%7 = getelementptr inbounds i8* %it.01, i64 1 ; [#uses=2 type=i8*]
%8 = icmp eq i8* %7, %3 ; [#uses=1 type=i1]
br i1 %8, label %._crit_edge, label %.lr.ph
._crit_edge: ; preds = %.lr.ph, %0
ret void
}
우리가 (혼란을 피하기 위해) 간단한 테스트 케이스를 사용하자
및 BOOST_FOREACH
:
; [#uses=0]
define void @_Z7foreachv() nounwind uwtable {
%1 = load i8** @HelloWorld, align 8, !tbaa !0 ; [#uses=1 type=i8*]
br label %2
; <label>:2 ; preds = %.preheader, %0
%.in = phi i8* [ %6, %.preheader ], [ %1, %0 ] ; [#uses=2 type=i8*]
%3 = load i8* %.in, align 1, !tbaa !1 ; [#uses=2 type=i8]
%4 = icmp eq i8 %3, 0 ; [#uses=1 type=i1]
br i1 %4, label %.critedge, label %.preheader
.preheader: ; preds = %2
%5 = sext i8 %3 to i32 ; [#uses=1 type=i32]
%putchar = tail call i32 @putchar(i32 %5) nounwind ; [#uses=0 type=i32]
%6 = getelementptr inbounds i8* %.in, i64 1 ; [#uses=1 type=i8*]
br label %2
.critedge: ; preds = %2
ret void
}
단순한 케이스에 대해서는 더 많은 지시 사항이 있지만 (2 개가 아닌 반복마다 하나씩) 더 많은 명령어가 있다고 말할 수 있습니다.하지만 성능을 고정시키는 것은 어려울 것입니다.
물론 ... 더 이상 중요하지 않습니다! 우박 C++ 11 : 당신이 (CONST) 참조를 사용하는 경우, 컴파일러는 어떤 변수가없는 별칭을 수행하는 것이 연구 만 열심히 시간을 가지고, 덜 생성
void bestfor() {
for(char const ch: HelloWorld) {
printf("%c", ch);
}
}
사이드 노트에서'typeof' 연산자는 이식 가능하지 않습니다. – fredoverflow
휴대용이 아니라는 것은 무엇입니까? 나는 이것이 표준의 일부가 아니라는 것을 안다. – balki
나는 옵티 마이저가 그 진술을 따라 잡았다 고 생각한다. BOOST_FOREACH를 사용하는 코드를 벤치마킹하여 동등한 for 루프를 사용하여 좀 더 성능을 끌어낼 수 있는지 확인했습니다. BOOST_FOREACH 코드가 조금 더 빨랐습니다 (즉, 아마도 오차 범위 내에있을 것입니다). – Ferruccio