お手軽for each
http://tricklib.com/cxx/ex/evil_for/
とっても楽に使えるC++版foreach。ネストも当然出来たりする。
パフォーマンスがちょっと心配だったんで実験してみました。
#include "vector" #include "evil_for.h" std::vectorarray; void loop_test1() { std::vector ::iterator p, pend = array.end(); for (p = array.begin(); p != pend; ++p) *p = 5; } void loop_test2() { evil_for(array) *evil_i(array) = 5; }
まずevil_forのコード量の少なさに感動してしまいました。
んでg++-4.1.0 -O3 -march=athlon-xp -Sした結果が以下の通り。(ちょっと加工してます)
_Z10loop_test1v: .LFB511: movl array+4, %edx movl array, %eax pushl %ebp cmpl %eax, %edx movl %esp, %ebp je .L20 .L19: movl $5, (%eax) addl $4, %eax cmpl %eax, %edx jne .L19 .L20: leave ret _Z10loop_test2v: pushl %ebp movl %esp, %ebp pushl %ebx leal -16(%ebp), %ebx subl $36, %esp movl array, %eax movl $_ZN14evil_for_tools15destruct_objectIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEEEvPv, -12(%ebp) movl %ebx, 4(%esp) movl %eax, -8(%ebp) leal -8(%ebp), %eax movl %eax, (%esp) call _ZN14evil_for_tools16duplicate_objectIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEEEvPvS8_ movl array+4, %edx cmpl %edx, -16(%ebp) je .L23 movl -16(%ebp), %eax .L24: movl $5, (%eax) addl $4, %eax cmpl %edx, %eax jne .L24 movl %eax, (%ebx) .L23: movl %ebx, (%esp) call *-12(%ebp) addl $36, %esp popl %ebx leave ret
ループ内は全く同じになってますね。素晴しい。evil_forを使うとちょっと前後にコードが入ってしまうのが残念。(特に関数呼び出し)
まあ呼ぶ関数自体も対した処理をしていないので殆どオーバーヘッドはないと思います。
これは良い物を知りました。ばりばり使わせて貰おうと思います。