CQ出版のインタフェース 2017-5 の記事のプログラム例に
for( i=0; i<256; i++){
for( y =0; y < Y; y++ ){
for( x = 0; x < X; x++){
p[0] = img -> imageData[img->widthStep* y + x*3 ]; //B(青色)
if(p[0]==i){hn[i]++;}
}
}
}
がありました。このリストを見て、無性にイライラするのは私だけでしょうか?
なぜ、i,y,x の3重のループで処理しないといけないのか、y,xの2重ループで十分ではないかと思います。
for( y =0; y < Y; y++ ){
for( x = 0; x < X; x++){
p[0] = img -> imageData[img->widthStep* y + x*3 ]; //B(青色)
hn[ p[0] ]++;
}
}
3重にするならせめて、y,x,i の順にしてp[0]への代入は1回で済ませればと思います。
for( y =0; y < Y; y++ ){
for( x = 0; x < X; x++){
p[0] = img -> imageData[img->widthStep* y + x*3 ]; //B(青色)
for( i=0; i<256; i++){
if(p[0]==i){hn[i]++;}
}
}
}
最近のコンパイラの最適化では、私の書いたようなコーディング(修正?)は無意味なのでしょうか?
No.1
- 回答日時:
貧乏じーさんプログラマです。
3重ループにしたのは紙面に余白が無かったからでしょう。
(○ページ以内でよろしく、みたいな。)
コードチェッカーとしては(私的にですが)3重ループ以上なんて許しません(たとえ3次元空間でも)。
もちろん2次元配列や、まさか3次元配列なんて、文法的に許されても常識的には使わない手法です。
回答ありがとうございます。
>3重ループにしたのは紙面に余白が無かったからでしょう。
イライラを軽減する解釈ありがとうございます。
でも、今回は該当しない感じです。
別の解釈ありましたら、よろしくお願いします。
No.2
- 回答日時:
30年ほどシステム開発の仕事をしていました。
処理したいことを明示的、直感的に示していればループの段数とか順番にこだわりません。
仕事仲間に「ソースコードはエッセーだ!」と言っている人間がいました。
ある意味そうだなぁと思います。
同じことをするにも幾つかのやり方がある場合が多く、何を選ぶかはその人の視野、経験、物の見方、そして最後に「好み」があると思うからです。
雑誌の例題とかは一般的なプログラム開発と違いソースコードを書く前に実装仕様を文書で示しませんので、意味合いをより明確に示せる書き方が好ましいと考えます。
ですので、ご質問に書かれている雑誌に掲載されていたコードが、処理の意味合いをより多くの人がソースコードを見て「こういうことをするのはこうすればよい」と容易に理解できる視点で出来ていれば私的には「なるほどね」と思うだけです。
参考まで。
回答ありがとうございます。
>同じことをするにも幾つかのやり方がある場合が多く、何を選ぶかはその人の視野、経験、物の見方、そして最後に「好み」があると思うからです。
同感です。ですから、人の書いたコードを読むのは、一つの楽しみになっています。
今回の事例は、筆者はいったい何を考えているのか? といったイライラが質問の発端です。言い換えれば、
>「こういうことをするのはこうすればよい」と容易に理解できる視点で出来ていれば
の前提条件が、本件では満たさないのがイライラの一因に思えますが、その点はいかがでしょう?
お礼を書きながら考えてみました。
「輝度値がiの画素ならば、hn[i]++ する」
という処理をなぜ、
「一番外側でiをループで回して、輝度値とiが一致したときhn[i]++する」
というコードが わかりやすいコード になることが理解できないです。
わざわざ、効率の悪いコードを書いている気がしてならないのですけど・・
ループに回すならせめて一番内側で回してほしいと感じてしまうのです。
No.3
- 回答日時:
処理速度が特に問題にならない、かつi=0~255の繰り返しをx,yの繰り返しの外側で行うほうが業務的に判りやすいなら、2017-5 の記事のプログラム例で問題がないかと思います。
但し、処理速度の観点からいえば、
あなたがかかれた2重ループの方法がベストかと思います。
(但し、p[0]の値が0~255であることが保障される場合です。保障されないなら、3重ループがベストになるかと)
回答ありがとうございます。
>保障されないなら、3重ループがベストになるかと
保障されないなら、ループではなく
if(0<=p[0] && p[0]<=255) {
の条件判定と思いますけど、という突っ込みはさておいて、
>外側で行うほうが業務的に判りやすいなら、
なるほど「業務的に判りやすい」ですね。そういう解釈、感謝です。
No.4ベストアンサー
- 回答日時:
利点を考えてみました
これを並列処理したときに
スレッド0: hn[0] に p[0] = 0 をカウント
スレッド1: hn[1] に p[0] = 1 をカウント
...
とすれば、
・img -> imageData は読み出すだけなので衝突しない
・hn[i] でアクセスする領域は、スレッド毎に i が違うので、同じ箇所に書き込まれることはない。
となり、排他処理が不要となります。
(もちろん、x,y,i,p[0]はスレッドでローカルな変数とします)
ただ、並列処理のオーバーヘッドや同時並列処理数等を考えると、こんな並列処理はしない方が効率的です。
あるいは、hn[]がシークに時間がかかる領域の場合、
hn[p[0]) で毎回違う位置を探しに行って、その時間が無視できないほどだったら、
先にhnを決めてしまった方が速くなるでしょう。
こちらも、非現実的です。
No.5
- 回答日時:
No.2です。
> 今回の事例は、筆者はいったい何を考えているのか? といったイライラが質問の発端です。言い換えれば、
> >「こういうことをするのはこうすればよい」と容易に理解できる視点で出来ていれば
> の前提条件が、本件では満たさないのがイライラの一因に思えますが、その点はいかがでしょう?
当方は「インタフェース2017-5」を購読していませんので詳しい内容はわかりません。
No.2にも同様のことを書きましたが、この3重ループが「このプログラムがやりたい事の処置手順」を分かりやすく示しているのであればそれでよいと思います。
それだけです。それにつきます。
で、それを満たしていれば自分の考え方とは違っていても「そういう見方もあるのか」と感じるだけで、イライラしたり「自分ならこうする」と強く主張したりはしません。
プログラムのロジックは仕様書の処理方式の記述内容に従っていたとしても最終的にはコーダーの観点が反映されるものだと思いますので、それをはなから否定して「こあらねばならない」ということはぜずコーダーの話を(説明を)聞きます。仕事の現場では後輩や部下に対してそのように接していました。
なお、現役時代はリアルタイム処理のように時間勝負の処理ではない限り「凝ったことは考えず出来るだけ平易に」、「コメントも分かりやすく」、「ソフトウェアは時に人より長生きするから」(←自分の転属・転職・退職の後も誰かが保守する等の意味合い)と指導していました。最初に書きました『この3重ループが「このプログラムがやりたい事の処置手順」を分かりやすく示しているのであればそれでよい』はそういう観点でのものです。
ちなみに雑誌などに掲載するプログラムとしては仕方ないですが、実プログラムとそしては256は直値ではなく意味が明示的に分かるものにdefineしたいですね。(^^;
変数等の名前も工夫したいし。。。
再度の回答ありがとうございます。
>それを満たしていれば自分の考え方とは違っていても「そういう見方もあるのか」
>と感じるだけで、イライラしたり「自分ならこうする」と強く主張したりはしません。
まったく同感です。ほとんどの場合は、その通りです。
前のお礼に書いたように、「そういう見方もあるのか」を知ることは、人の作ったプログラムを読む楽しみの一つでもあります。
普通であれば、馬鹿だなこのプログラマ、で終わるのですが、掲載された雑誌が
CQ出版のインタフェース 2017-5なので、私の配慮不足で何か意義があるのでは、と深読みをして、これといった解釈が得られずに無性にイライラして質問した次第です。
今回質問した案件では、前提条件の、
「このプログラムがやりたい事の処置手順」を分かりやすく示している
とは思えないので、No3さんや、No4さんの回答のように、
私が気が付かないメリット、
なるほど「そういう見方もあるのか」といった見方
を教えていただきたく質問しています。
No.7
- 回答日時:
これかぁ。
> // 最大となるピンの画素数を獲得
とあるので、おそらく著者は
「最大となるピンの画素数を獲得」
というプログラムが必要と考え
最大ピンの画素数=0
for ( 全ての色レベル について ) {
if 該当色レベルの画素数>現在の最大ピンの画素数 then
最大ピンの画素数 = 該当色レベルの画素数 に更新
end if
}
というアルゴリズムに辿りついた。
ここで「該当色レベルの画素数」をどうやって調べるか、というときに
最大ピンの画素数=0
for ( 全ての色レベル について ) {
「該当色レベルの画素数を数える」 ← ここ
if 該当色レベルの画素数>現在の最大ピンの画素数 then
最大ピンの画素数 = 該当色レベルの画素数 に更新
end if
}
として、これをそのままプログラムにした。
というところでしょうか。
この通りなら、著者の考え通りのプログラムということになります。
効率はともかく。
さらなる回答ありがとうございます。
教えてくださったページ、意味不明です・・
> // 最大となるピンの画素数を獲得
そのようなコメントはソースリストにないですが、
「該当色レベルの画素数を数える」
という処理が 筆者の基本パターン として刷り込まれていれば可能性ありますね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- Perl RSSにdiv,ul classを付けたいのですがどのようにつけるのかわからないです 2 2022/03/28 01:53
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- C言語・C++・C# LU分解法のピボッティングについて(C言語/gcc-9) 3 2022/07/11 23:10
- その他(プログラミング・Web制作) pythonのグローバル変数 2 2022/11/25 18:02
- C言語・C++・C# LU分解法のピボット選択機能実装について(C言語・gcc-9) 1 2022/07/22 15:20
- JavaScript アップロードファイルの種類によって処理を分岐させたいのですが書き方が分からずアドバイスお願いします 4 2023/06/17 19:12
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
- その他(プログラミング・Web制作) ラムダ式 3 2022/11/28 16:48
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
小数点を含む数値かどうか判断...
-
Excelでのセル内容の高速消去方法
-
SQLの速度をあげるには・・・
-
win10で、正確な待ち時間の作り方
-
Excel VBAにて、2GB超の点群デ...
-
ヤフーファイナンスからデータ...
-
プログラミングの授業でPython...
-
再帰呼び出しを使いますか?
-
プログラム上のCPU稼働率低減に...
-
偶数次魔方陣のプログラム
-
絶対パスの取得について
-
ゲームプログラミングの乱数で...
-
ノットイコールを教えて下さい
-
PCの並列化
-
WebBrowserの読み込み待ちの処...
-
LINUX QT上でパソコンのシャッ...
-
DoEvents関数って何?
-
ナップザック問題?をエクセル...
-
関数呼び出しの処理
-
C言語 時刻差分の算出方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excelでのセル内容の高速消去方法
-
DoEvents関数って何?
-
SQLの速度をあげるには・・・
-
小数点を含む数値かどうか判断...
-
win10で、正確な待ち時間の作り方
-
Excel(VBA)でSetTimer関数を使...
-
絶対パスの取得について
-
WebBrowserの読み込み待ちの処...
-
Excel VBAにて、2GB超の点群デ...
-
VBでの簡易電卓の作成(減算方...
-
テキストファイルの空行をスキ...
-
ノットイコールを教えて下さい
-
ナップザック問題?をエクセル...
-
If Not c Is Nothing Then ~延...
-
プログラム上のCPU稼働率低減に...
-
逆ポーランド記法における単項...
-
符号付きにすべきか、符号なし...
-
C言語 時刻差分の算出方法
-
C言語:関数を使うメリットとデ...
-
Excel VBA データ削除の高速化
おすすめ情報