質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

5回答

2508閲覧

何度も頻繁に同じ値を代入することにデメリットはありますか?

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

1グッド

2クリップ

投稿2017/03/24 10:48

例えば下記のような「メンバに代入されたらフラグを立てておく」みたいなコードが何度も頻繁にも呼ばれる場合、

c#

1//初期値のみfalseでリセットはされない 2bool Flag = false; 3int m_Num; 4 5public int Num { 6 set { 7 m_Num = value; 8 Flag = true; 9 } 10}

m_Numは毎回代入するとして、フラグは一回だけ立てればよいので、

c#

1public int Num { 2 set { 3 m_Num = value; 4 5 if(!Flag) 6 Flag = true; 7 } 8}

このようにifを挟んだ方が良いのでしょうか?
また、上記ではboolにしましたが他の型の場合はどうなのでしょうか?

raccy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

結論からいうと、どっちでもいいです。

同じ値を何度代入しようが、基本的に問題はないです。
型によって問題になることがあるとすれば、パフォーマンス上の問題くらいです。

本件に限らず、一般的な指針としてですが、
パフォーマンスについては「予測するな、計測せよ」という格言があります。

実際に最小限のコードで5万回とか10万回とかfor文でループさせてみて、
処理速度に差が出るか、タスクマネージャーを開いてCPUや使用メモリに差がでるか
計測してみましょう。

たとえば10万回のループで数ミリ秒程度の差だったとしたら、
そんな差が実際のプロダクトで目に見える形で問題になることは
(よっぽどシビアなものでなければ)通常は無いはず。
そういう場合は、些細な性能よりもコードの読みやすさを優先して書くことのほうが
ずっと重要だと思います。

投稿2017/03/24 12:57

oika

総合スコア425

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/03/25 03:48

回答ありがとうございました。 すっかり失念していましたが、可読性も重要ですね。
guest

0

既に解決済みとなっていましたが、
具体的に何故早いのかが書かれていなかった為回答させていただきます。

結論からするとif比較無しの方が早いです。
何故か、についてはコンパイルされたファイルをILレベルで見て下さい。
※ILSpy, JustDecompile, DotPeek, dnSpy... などILを見る為のツールは沢山あります。

ご存知かとは思いますがC#は中間言語(IL)を出力します。
その中間言語がどれだけのステップ数があるかが基準になります。

実例

以下のコードは以下の画像のようなILが出力されます。
圧倒的にif比較なしILの方が少ないステップ数となっています。
よって、if比較無しの方が早いとなります。

※出力されるILは最適化オプションなどによっても変化しますが、
今回の簡単なコードの場合はどの環境でも大差は無いと思われます。

C#

1static bool flag = false; 2 3static void Function1() 4{ 5 flag = true; 6} 7 8static void Function2() 9{ 10 if (!flag) 11 { 12 flag = true; 13 } 14}

投稿2017/03/29 05:27

編集2017/03/29 05:30
aglkjggg

総合スコア769

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

マルチスレッドでFlagがグローバルの場合は、if()判定は要注意ですd^^
素直に毎回代入の方がいいと思います。
[追記]
if()がなくても、スレッドセーフにはなりませんが・・・^^;

投稿2017/03/24 13:09

編集2017/03/24 20:54
cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/03/25 03:55

回答ありがとうございました。 まだマルチスレッドを扱ったことはないのですが、覚えておきたいと思います。
guest

0

代入処理と判定処理のどちらの方が低コストなのかによります。

代入処理を削減したとしても、判定処理が必要なのでこちらの方が重いならば本末転倒です。

投稿2017/03/24 13:03

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/03/25 03:51

回答ありがとうございました。 負荷を比較して判断したいと思います。
guest

0

ベストアンサー

こんにちは。

ケースバイケースです。

Flagが単なるフィールドでしたら、一々判定するより毎回代入した方が一般に速いと思います。
Flagがfalseの場合「Flagを取り出してflaseならFlag=true;の次へジャンプ」という処理が行われます。それよりFlag=true;の方が高速に実行できる場合が多いです。

Flagがプロパティでget処理は軽くset処理が重い場合は、毎回代入するより、trueの時だけ代入するようにすることで全体として軽くなる可能性が高いと思います。
もちろん、set処理に副作用(何か他の値を変更する。例えばカウントアップする等)がある時はその副作用に応じて対処する必要があります。

bool以外の場合も基本的な考え方は同じで良いと思います。

投稿2017/03/24 11:07

編集2017/03/24 11:10
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/03/25 03:36

回答ありがとうございました。 実際の負荷を見ながら適切な方を選択したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問