C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: 比較演算子の効率の良い書き方


(過去ログ 66 を表示中)

[トピック内 16 記事 (1 - 16 表示)]  << 0 >>

■38299 / inTopicNo.1)  比較演算子の効率の良い書き方
  
□投稿者/ 玉 (1回)-(2009/07/10(Fri) 16:39:21)

分類:[.NET 全般] 

初めまして。いつもお世話になります。
今回初めて質問させていただくのですが、タイトルにも書きました通り
比較演算子の効率の良い書き方を教えていただきたいのです。

例えば条件で
If 変数 >= 5 と If 変数 > 4 は同じ処理をしてくれますがデータが膨大になると
効率で考えると>を使う方が処理として早くなると思うのですが、>=だと>か=を判断してから
結果としてtrueかfalseを返しているので、2度判断しているからなのかなと考えていました。

そこで、今回Textboxに入力された値以上の場合、スプレッドシートにその値以上のものを全て
表示するという処理を行っていたのですが、始めに当然>=を使って表示する処理をしていましたが
上記のことを考えた上で出した結果が<を使用してそれのNotを使うんじゃないかと思い、それで
作成したのですが結局<をかませてからNotをしているので結局2度判断していたのであまり関係が
ありませんでした。

何か効率を良くしつつソースとしても見やすい案はないでしょうか?もしよろしければご教授お願い
致します。

開発環境はVB.NET 2005, Access2003です。よろしくお願い致します。
引用返信 編集キー/
■38301 / inTopicNo.2)  Re[1]: 比較演算子の効率の良い書き方
□投稿者/ れい (853回)-(2009/07/10(Fri) 16:46:31)
No38299 (玉 さん) に返信
> If 変数 >= 5 と If 変数 > 4 は同じ処理をしてくれますが

「変数」が整数型なら。

> データが膨大になると
> 効率で考えると>を使う方が処理として早くなると思うのですが、>=だと>か=を判断してから
> 結果としてtrueかfalseを返しているので、2度判断しているからなのかなと考えていました。

確認しましたか?
ループでまわせば簡単に確認できますので、
確認しておくとよいと思います。


> そこで、今回Textboxに入力された値以上の場合、スプレッドシートにその値以上のものを全て
> 表示するという処理を行っていたのですが、始めに当然>=を使って表示する処理をしていましたが
> 上記のことを考えた上で出した結果が<を使用してそれのNotを使うんじゃないかと思い、それで
> 作成したのですが結局<をかませてからNotをしているので結局2度判断していたのであまり関係が
> ありませんでした。

こちらも理由と共に確認しましたか?

私の「勘」だと、どれもほぼ同じ速度になるはずです。

> 何か効率を良くしつつソースとしても見やすい案はないでしょうか?もしよろしければご教授お願い
> 致します。

それは皆が考える所で、いろいろな基準があると思います。
私なら「意味がわかるように」作ります。
速度はとりあえず考慮せず、一番楽に読めるようにつくり、速度が必要なところだけなおします。


引用返信 編集キー/
■38302 / inTopicNo.3)  Re[2]: 比較演算子の効率の良い書き方
□投稿者/ みきぬ (525回)-(2009/07/10(Fri) 16:53:30)
> 何か効率を良くしつつソースとしても見やすい案はないでしょうか?もしよろしければご教授お願い
> 致します。

参考までに、私の場合は仕様書の日本語通りに書こうとします。
「A が B 以上」なら A >= B 、「A が B 未満」なら A < B といった具合。
そのほうが、後で読む人がわかりやすいと思うので。

# その結果ソースが "必要以上に" 見づらくなるのであれば、それは元の日本語が悪いっつーことで
引用返信 編集キー/
■38303 / inTopicNo.4)  Re[1]: 比較演算子の効率の良い書き方
□投稿者/ .SHO (961回)-(2009/07/10(Fri) 16:56:01)
2009/07/10(Fri) 17:03:16 編集(投稿者)

> If 変数 >= 5 と If 変数 > 4 は同じ処理をしてくれますがデータが膨大になると
> 効率で考えると>を使う方が処理として早くなると思うのですが

ならないと思います。


仮にそんなことで速くなるならば、コンパイラが最適化の時点で
勝手に、>= 5 を > 4 に直してくれます。

引用返信 編集キー/
■38304 / inTopicNo.5)  Re[2]: 比較演算子の効率の良い書き方
□投稿者/ 玉 (2回)-(2009/07/10(Fri) 17:11:55)
>>If 変数 >= 5 と If 変数 > 4 は同じ処理をしてくれますが
>
> 「変数」が整数型なら。

整数型です。

>>データが膨大になると
>>効率で考えると>を使う方が処理として早くなると思うのですが、>=だと>か=を判断してから
>>結果としてtrueかfalseを返しているので、2度判断しているからなのかなと考えていました。
>
> 確認しましたか?
> ループでまわせば簡単に確認できますので、
> 確認しておくとよいと思います。
>
>>そこで、今回Textboxに入力された値以上の場合、スプレッドシートにその値以上のものを全て
>>表示するという処理を行っていたのですが、始めに当然>=を使って表示する処理をしていましたが
>>上記のことを考えた上で出した結果が<を使用してそれのNotを使うんじゃないかと思い、それで
>>作成したのですが結局<をかませてからNotをしているので結局2度判断していたのであまり関係が
>>ありませんでした。
>
> こちらも理由と共に確認しましたか?
>
> 私の「勘」だと、どれもほぼ同じ速度になるはずです。

確認をしっかりしていませんでした。すみません。DateTimeを使用して処理にかかった時間を計測
したところ、約500件でほぼ差がなし、約5000件でもほぼ変わらない状態(0.05±?程度)でした。


>
>>何か効率を良くしつつソースとしても見やすい案はないでしょうか?もしよろしければご教授お願い
>>致します。
>
> それは皆が考える所で、いろいろな基準があると思います。
> 私なら「意味がわかるように」作ります。
> 速度はとりあえず考慮せず、一番楽に読めるようにつくり、速度が必要なところだけなおします。
>

ありがとうございました。可読性のことも考えた上で、仕様上は〜以上と書いていたので
始めは>=で作成していたのですが、一つ一つに対してもこだわれと言われてからこの演算子の使い方
にも混乱してしまいました。まず「意味がわかるように」作成したいと思います。
ありがとうございました。
引用返信 編集キー/
■38305 / inTopicNo.6)  Re[2]: 比較演算子の効率の良い書き方
□投稿者/ 玉 (3回)-(2009/07/10(Fri) 17:16:34)
> 何か効率を良くしつつソースとしても見やすい案はないでしょうか?もしよろしければご教授お願い
> 致します。

> 参考までに、私の場合は仕様書の日本語通りに書こうとします。
> 「A が B 以上」なら A >= B 、「A が B 未満」なら A < B といった具合。
> そのほうが、後で読む人がわかりやすいと思うので。

> # その結果ソースが "必要以上に" 見づらくなるのであれば、それは元の日本語が悪いっつーことで

やはり仕様書通りに作成することに重点を置くべきですよね。それてしまったら違うという話に
なってしまいますよね。もう一度、言葉通りに意味がわかりやすい、以上なら>= 未満なら< で
作成してみようと思います。その際にも、こうこうという考えで作成しましたと伝えようと思います。
ありがとうございました。
引用返信 編集キー/
■38306 / inTopicNo.7)  Re[2]: 比較演算子の効率の良い書き方
□投稿者/ 玉 (4回)-(2009/07/10(Fri) 17:21:15)
No38303 (.SHO さん) に返信
> 2009/07/10(Fri) 17:03:16 編集(投稿者)
>
>>If 変数 >= 5 と If 変数 > 4 は同じ処理をしてくれますがデータが膨大になると
>>効率で考えると>を使う方が処理として早くなると思うのですが
>
> ならないと思います。
>
>
> 仮にそんなことで速くなるならば、コンパイラが最適化の時点で
> 勝手に、>= 5 を > 4 に直してくれます。
>

ありがとうございます。勝手に直してくれるというわけではなく、その前の判断で考えるなら
>=はどのサイトを見ても説明としてはより大きいか、等しいかと書いています。つまり
If a > 5 or a = 5 という判断をしてるという私の考えはおかしいでしょうか?

引用返信 編集キー/
■38307 / inTopicNo.8)  Re[3]: 比較演算子の効率の良い書き方
□投稿者/ .SHO (962回)-(2009/07/10(Fri) 17:24:05)
2009/07/10(Fri) 17:24:30 編集(投稿者)

> If a > 5 or a = 5 という判断をしてるという私の考えはおかしいでしょうか?

おかしいです。

>= も > もアセンブラレベルで考えれば、1命令で実行できるので
2回の判断に分ける必要はないです。

引用返信 編集キー/
■38308 / inTopicNo.9)  Re[1]: 比較演算子の効率の良い書き方
□投稿者/ よねKEN (370回)-(2009/07/10(Fri) 17:30:01)
2009/07/10(Fri) 17:46:46 編集(投稿者)

> 例えば条件で
> If 変数 >= 5 と If 変数 > 4 は同じ処理をしてくれますがデータが膨大になると
> 効率で考えると>を使う方が処理として早くなると思うのですが、>=だと>か=を判断してから
> 結果としてtrueかfalseを返しているので、2度判断しているからなのかなと考えていました。

VBやC#がコンパイルされて生成されるILのレベルで言うと、
VBだとたぶん「>=」はbge命令にコンパイルされるので、2度は判断しません。
C#だと最適化なしでは「>=」は、clt、ldc.i4.0、ceqの3命令にコンパイルされるはずなので、2度判断します。
C#でも最適化ありだとbge命令にコンパイルされるので、2度は判断しません。
以上はILのレベルでの話なので、JITコンパイルされた後にどんな命令になるかは知りませんが、
IL命令レベルでは一応生成される命令数に差異はある場合があります。

しかし、1万回くらい繰り返してもその差を測定できない程度の違いですので、
他の方がおっしゃっているように読み易さ優先でよいと思います。

<修正>
以下の場所を修正しました。(本文は直してあります)

> C#だと最適化なしでは「>=」は、cgt、ldc.i4.0、ceqの3命令にコンパイルされるはずなので、2度判断します。

(誤) 「cgt、ldc.i4.0、ceqの3命令」
(正) 「clt、ldc.i4.0、ceqの3命令」
    ~~~
</修正>


引用返信 編集キー/
■38309 / inTopicNo.10)  Re[3]: 比較演算子の効率の良い書き方
□投稿者/ みきぬ (526回)-(2009/07/10(Fri) 17:31:51)
No38306 (玉 さん) に返信
> If a > 5 or a = 5 という判断をしてるという私の考えはおかしいでしょうか?
> 
IL を覗いてみると、そんな感じの判断になってるような気がします。
# IL をきちんと読めないので勘

public static bool a1(int a)
{
    return a >= 4;
}

public static bool a2(int a)
{
    return a > 4;
}

.method public hidebysig static bool  a1(int32 a) cil managed
{
  // コード サイズ       8 (0x8)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.4
  IL_0002:  clt
  IL_0004:  ldc.i4.0
  IL_0005:  ceq
  IL_0007:  ret
} // end of method Program::a1

.method public hidebysig static bool  a2(int32 a) cil managed
{
  // コード サイズ       5 (0x5)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.4
  IL_0002:  cgt
  IL_0004:  ret
} // end of method Program::a2

※Visual Studio 2005 の Release ビルドにて確認

引用返信 編集キー/
■38310 / inTopicNo.11)  Re[4]: 比較演算子の効率の良い書き方
□投稿者/ よねKEN (371回)-(2009/07/10(Fri) 17:35:48)
2009/07/10(Fri) 17:38:23 編集(投稿者)

No38309 (みきぬ さん) に返信
> ■No38306 (玉 さん) に返信
>>If a > 5 or a = 5 という判断をしてるという私の考えはおかしいでしょうか?
>>
> IL を覗いてみると、そんな感じの判断になってるような気がします。
> # IL をきちんと読めないので勘

コンパイラがVBかC#か、最適化ありかなしか、
条件式をIf文などの分岐命令の中で使うかどうかで出力される結果に影響があります。

c〜系の比較命令には、「>=」「<=」に当たる命令はなぜか用意されていません。
それに対してb〜系の分岐命令には、「>=」「<=」に当たる命令も用意されています。

ですので、比較結果のtrue/falseを返すメソッドで実験するとb系ではなくc系を使うため、
その結果になります。同様の内容をif文の中で実験するとVB/C#の最適化ありでは
bge命令が使われると思います。

C#で最適化なしの場合はこの実験のようにc系の命令が使われると思います。
引用返信 編集キー/
■38311 / inTopicNo.12)  Re[2]: 比較演算子の効率の良い書き方
□投稿者/ みきぬ (527回)-(2009/07/10(Fri) 17:36:25)
VB でもやってみたけど、同じっぽいなあ…他にも条件があるのかな?

Function a1(ByVal a As Integer) As Boolean
Return a >= 4
End Function

Function a2(ByVal a As Integer) As Boolean
Return a > 4
End Function


.method public static bool a1(int32 a) cil managed
{
// コード サイズ 8 (0x8)
.maxstack 2
.locals init ([0] bool a1)
IL_0000: ldarg.0
IL_0001: ldc.i4.4
IL_0002: clt
IL_0004: ldc.i4.0
IL_0005: ceq
IL_0007: ret
} // end of method Module1::a1

.method public static bool a2(int32 a) cil managed
{
// コード サイズ 5 (0x5)
.maxstack 2
.locals init ([0] bool a2)
IL_0000: ldarg.0
IL_0001: ldc.i4.4
IL_0002: cgt
IL_0004: ret
} // end of method Module1::a2

引用返信 編集キー/
■38312 / inTopicNo.13)  Re[5]: 比較演算子の効率の良い書き方
□投稿者/ みきぬ (528回)-(2009/07/10(Fri) 17:42:22)
No38310 (よねKEN さん) に返信
> ですので、比較結果のtrue/falseを返すメソッドで実験するとb系ではなくc系を使うため、
> その結果になります。同様の内容をif文の中で実験するとVB/C#の最適化ありでは
> bge命令が使われると思います。
>
なるほどー。試してみた。

public static bool a3(int a)
{
if (a >= 5)
{
return true;
}
else
{
return false;
}
}
public static bool a4(int a)
{
if (a > 5)
{
return true;
}
else
{
return false;
}
}

.method public hidebysig static bool a3(int32 a) cil managed
{
// コード サイズ 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.5
IL_0002: blt.s IL_0006
IL_0004: ldc.i4.1
IL_0005: ret
IL_0006: ldc.i4.0
IL_0007: ret
} // end of method Program::a3

.method public hidebysig static bool a4(int32 a) cil managed
{
// コード サイズ 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.5
IL_0002: ble.s IL_0006
IL_0004: ldc.i4.1
IL_0005: ret
IL_0006: ldc.i4.0
IL_0007: ret
} // end of method Program::a4

とりあえずすっきり。

# 言いたかったのは、おかしいとは言い切れないんじゃない? てことだったりする
引用返信 編集キー/
■38313 / inTopicNo.14)  Re[3]: 比較演算子の効率の良い書き方
□投稿者/ 玉 (5回)-(2009/07/10(Fri) 17:52:25)
みなさんありがとうございます。自分の能力不足でILなどを調べている間に
レスをつけるのが遅れてしまいました。1万件の場合でも処理にかかった時間を
比べてみましたが0.07±程度でした。もう一度IL命令レベルというのを詳しく
調べてみようと思います。ありがとうございます。
引用返信 編集キー/
■38318 / inTopicNo.15)  Re[4]: 比較演算子の効率の良い書き方
□投稿者/ なちゃ (311回)-(2009/07/10(Fri) 18:54:19)
整数の比較って処理の中では極めて軽い部類に入るはずですので
1回増えたくらいで有意な差が出ることはまずないでしょう。
# 単純に1回の処理時間で計れるものではないですが

大抵はほかの処理の影響の方が大きすぎるのが普通でしょう。

ちなみに、DateTime.Nowでの計測は、その計測区間内で
推測で30ミリ秒程度までは測定誤差の可能性があります。

引用返信 編集キー/
■38397 / inTopicNo.16)  Re[5]: 比較演算子の効率の良い書き方
□投稿者/ 玉 (6回)-(2009/07/13(Mon) 15:32:25)
先日はありがとうございました。
パフォーマンスの測定などをして結果としてほぼ目に見えるほどの差がなかったということで
結果として可読性を重視し>=を使用する形を取ることにしました。
皆様ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -