channel数が未定の画像クラスのデータ配列をある特定の値で初期化することを考えます。channels数が未定の場合は画素単位辺りの初期化データサイズは可変となります。channel数が3で変数型が1byteの型なら3byte、channel数が1で変数型が4byteの型なら4byteというように様々なbyte数になる可能性がある場合です。
このような条件での書き方は様々だと思いますが、下記の二つの書き方は私が思いついたものです。
Method A: ポインタをインクリメントさせてひとつひとつ要素を初期化する
uchar src_elem[3] = {255, 0, 255};
int elem_size = 3;
int length = 100000000;
int num_of_channels = 3;
int num_of_elem = length * num_of_channels;
uchar data = new uchar[num_of_elem];
{
uchar *ptr = data;
uchar *end_ptr = ptr + num_of_elem;
const uchar *end_c;
const uchar *elem_ptr;
end_c = src_elem + elem_size/sizeof(uchar);
while(ptr!=end_ptr){
for(elem_ptr=src_elem; elem_ptr!=end_c; ++ptr, ++elem_ptr){
*ptr = *elem_ptr;
}
}
}
delete[] data;
Method B: 画素ごとにmemcpyでchannels数分の要素を一気に初期化する
uchar src_elem[3] = {255, 0, 255};
int elem_size = 3;
int length = 100000000;
int num_of_channels = 3;
int num_of_elem = length * num_of_channels;
uchar data = new uchar[num_of_elem];
{
uchar *ptr = data;
uchar *end_ptr = ptr + num_of_elem;
for(; ptr!=end_ptr; ptr+=num_of_channels){
memcpy(ptr, src_elem, elem_size);
}
}
delete[] data;
どちらが適しているか判断できなかったので速度計測を行ってみました。下記の表はchannel数3、画素数10000000のデータ配列をそれぞれの方法で30回初期化した平均をとった速度計測結果です。
実験環境
OS: Windows 7 64bit
CPU: core-i7 930 @2.80GHz
Memory: 6.00GB
Compiler: Visual C++ 64bit
Debug | Release | |
Method A | 1336 ms | 128 ms |
Method B | 976 ms | 117 ms |
これら二つを上記の環境で比較した場合はmemcpyを使う方法の方が速い結果になりました。もちろん他にも良い書き方があると思いますので、知っている方がいましたらご教授いただけると嬉しいです。