無差別に技術をついばむ鳥

情報処理技術全般を気まぐれに研究するブログです

C#をつつく26−引数の参照渡し。時には曖昧にしておくのがベスト。

今回は要望があったメソッド引数への参照引き渡しをつつくよ。メソッドへの値の渡し方は、 値引き渡し参照引き渡しの2つがあるんだ。 この2つの違いは、代名詞と固有名詞の違いと覚えておくといいピヨ。これはどういうことか現実の話しで例えるピヨ。
値渡しの場合は、「この原価計算報告書を部長に渡してね」と直接対象を指して言っているのと同じなんだ。一方参照渡しの場合は、「この書類部長に渡してね」と間接的に対象を指しているということなんだ。つまり、この2つの言い方の違いは、 替えが可能かどうかなんだ。 先ほどの例で言うと、原価計算報告書と違う書類を渡した時、 値引き渡しの場合は「おいおい○○。これ原価計算報告書じゃないぞ。」と注意されるのに対して、 参照引き渡しの場合は何も言われない。だって「書類」って曖昧に言っているからね。
何故このように2つの引渡し方法がC#にあるのかというと、 プログラムの柔軟性効率性を高めようとしているからなんだよ。 論よりもプログラミング。毎度御馴染みサンプルコードを実行してからよく見て。

using System;
using System.Diagnostics;

namespace RefParameter
{
    class Program
    {
        static void Main( string[ ] args ) {
            Stopwatch watch = new Stopwatch( );
            const int max = 1000000;
            double result = 0;

            //値引渡し
            watch.Start( );
            for(int i = 0; i < max; i++) {
                result = Calculate( i );
                //resultを使って何かの計算をする            
            }
            watch.Stop();
            Console.WriteLine( 
                "値引渡し時の実行時間は{0}ミリ秒です。", 
                watch.ElapsedMilliseconds );

            //参照引渡し
            watch.Reset( );
            watch.Start( );
            for ( double i = 0; i < max; i++ ) {
                result = i;
                RefCalculate( ref result );
                //resultを使って何かの計算をする
            }
            watch.Stop( );
            Console.WriteLine( 
                "参照引渡し時の実行時間は{0}ミリ秒です。", 
                watch.ElapsedMilliseconds );
        }

        private static double Calculate( int value ) {
            return value * DateTime.Now.Ticks;
        }

        private static void RefCalculate( ref double value ) {
            value *= DateTime.Now.Ticks;
        }
    }
}

どう?値引渡しと参照引渡しどちらが速かった?この状況で参照引き渡しの方が速い理由は 同じ変数を使いまわせるからなんだ。 値引渡しの場合は実行環境が毎回値を作成しているから、何度も使いまわしする場合にはスピードが落ちるんだ。 だから、参照引渡しの使い方をマスターしておくと、より効率がいいプログラムが組めるんだよ。 何度も試してマスターしておこう。
でも正直に言うと、このサンプルのスピードは、引渡し方法だけではなくてボックス化が影響しているんだけど、それについては難しいから今後説明するピヨ。
説明終わり。ということでこの記事は終わり。
別窓 | C# | コメント:4 | トラックバック:1 | ∧top | under∨
<<C++/CLIをつつく26−引数の参照渡し。時には曖昧にしておくのがベスト。 | 無差別に技術をついばむ鳥 | 中の人の徒然草44>>

この記事のコメント

値渡しは int を渡していますが、参照渡しは double を渡しています。それぞれのメソッドで行っている計算で、計算に使っている変数の型が違うため、キャストに時間がかかっていると思われます。試しに、全ての変数を long で統一すると、実行時間に有意な差は見られませんでした。確認願います。

また、C# のほとんどのクラスは参照型のため、参照の参照渡しと、参照の値渡しに、実行速度における差は、それほどないと思います。もちろんここでは値型を渡しているので差は出ると思いますが、32ビットの int 型を値渡しするのと、double 型を参照渡しするのとで、それほど差が出るとは思えません。この点も、確認願います。
2009-05-21 Thu 23:12 | URL | Jitta #-[ 内容変更]
Jittaさんへ
これについては、後にボックス化の説明をするために、
わざとこうしています。
ボックス化とキャストの違いは教えておいたいいと考えたわけです。
あと、パフォーマンスは小さな差から出てきます。
バイナリを弄くっているという事もあるかと思いますが、
私はボックス化/アンボックスを重視ししています。
これについては価値観の違いだと思います。
2009-05-22 Fri 08:33 | URL | インドリ #-[ 内容変更]
トラバックしてくれるのはいいんだけど、そっちにアクセスできませんので返答が出来ません。
ごめんね。
2009-05-23 Sat 09:08 | URL | インドリ #vAVnCpGk[ 内容変更]
アク禁にされていても、魚拓を通せば見れますよ。

http://s01.megalodon.jp/2009-0523-0955-57/blogs.wankuma.com/jitta/archive/2009/05/22/173455.aspx

コメントはできないけどね。
2009-05-23 Sat 09:57 | URL | p #-[ 内容変更]
∧top | under∨

コメントの投稿

 

管理者だけに閲覧
 

この記事のトラックバック

ちょっと違和感(C# で参照渡し) …
2009-05-22 Fri 22:29 何となく Blog by Jitta
∧top | under∨
| 無差別に技術をついばむ鳥 |