fc2ブログ

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;
        }
    }
}

どう?値引渡しと参照引渡しどちらが速かった?この状況で参照引き渡しの方が速い理由は 同じ変数を使いまわせるからなんだ。 値引渡しの場合は実行環境が毎回値を作成しているから、何度も使いまわしする場合にはスピードが落ちるんだ。 だから、参照引渡しの使い方をマスターしておくと、より効率がいいプログラムが組めるんだよ。 何度も試してマスターしておこう。
でも正直に言うと、このサンプルのスピードは、引渡し方法だけではなくてキャストが影響しているんだけど、それについては難しいから今後説明するピヨ。
説明終わり。ということでこの記事は終わり。
追記:
この記事はボックス化を同時に説明しようとして失敗しました。そこで、只今応急処置としてボックス化をキャストへ修正しました。後日改めて「ボックス化/アンボックス化」、「参照引渡し」、「キャスト」、「ボックスとキャストの違い」を各記事に分けて書きます。
スポンサーサイト



テーマ : プログラミング
ジャンル : コンピュータ

トラックバック


この記事にトラックバックする(FC2ブログユーザー)

ちょっと違和感(C# で参照渡し)

ちょっと違和感(C# で参照渡し)

コメントの投稿

非公開コメント

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

また、C# のほとんどのクラスは参照型のため、参照の参照渡しと、参照の値渡しに、実行速度における差は、それほどないと思います。もちろんここでは値型を渡しているので差は出ると思いますが、32ビットの int 型を値渡しするのと、double 型を参照渡しするのとで、それほど差が出るとは思えません。この点も、確認願います。

Jittaさんへ
これについては、後にボックス化の説明をするために、
わざとこうしています。
ボックス化とキャストの違いは教えておいたいいと考えたわけです。
あと、パフォーマンスは小さな差から出てきます。
バイナリを弄くっているという事もあるかと思いますが、
私はボックス化/アンボックスを重視ししています。
これについては価値観の違いだと思います。

トラバックしてくれるのはいいんだけど、そっちにアクセスできませんので返答が出来ません。
ごめんね。

アク禁にされていても、魚拓を通せば見れますよ。

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

コメントはできないけどね。

素朴な疑問

どこにボックス化が出てくるんだろう??

Re: タイトルなし

> アク禁にされていても、魚拓を通せば見れますよ。
>
> http://s01.megalodon.jp/2009-0523-0955-57/blogs.wankuma.com/jitta/archive/2009/05/22/173455.aspx
>
> コメントはできないけどね。

ありがとう。読んだよ。



それで感想なんだけど、これって価値観の違いだよね。
ボックス化とキャストを混同している人に会った事があるから少しずつ解説しようと思ったんだけど・・・
なんというか、先入観が強い人の様な気がします。
根拠無く私が見下しているといってみたり、よく分からないけど情報処理技術者じゃないと私に言ってみたり・・・
自分の好みに合わないってだけで言われても困ります。
人は十人十色なのです。
その事を分かっていただきたいものです。

Re: 素朴な疑問

> どこにボックス化が出てくるんだろう??

確かにそれについては間違っていますね。
キャストとボックス化を一度に解説しようとしてミスったかな?

Jitta さんへ
書き方でかちんときたけど確かにミスはありました。
申し訳ございませんでした。

>それで感想なんだけど、これって価値観の違いだよね。

二人ともサンプルコード(誰が動かしても同じ動きをするもの)を提示していますし、そのコードは実行時間を計測する以外の機能はないわけですから、どこに価値観の相違が入り込むのかなあ?

本番稼動後にユーザーから不具合を指摘されて「それは後で直すつもりだったからバグではありません」と言っても通用しませんよ?
暫定リリースなら暫定リリースでシステムの整合性は取れている必要があるのではないでしょうか?

インドリさんのサンプルコードが今後の解説の追加で最終的にどう変わっていくのか楽しみにしておりますが、値引き渡しと 参照引き渡しの説明でイキナリ実行速度のみにスポットライトをあてたサンプルコードというのは理解する上で危険だと思いますので、不足している説明を早めに追加して問題ないサンプルコードに仕上げることを希望いたします。

ごめんなさい。
書いている間に謝罪されていましたね。

あまり構えずきっちり向き合えば、その「謝罪」は「お礼」になると思いますよ。

がんばりましょう。

Re: タイトルなし

> ごめんなさい。
> 書いている間に謝罪されていましたね。
>
> あまり構えずきっちり向き合えば、その「謝罪」は「お礼」になると思いますよ。
>
> がんばりましょう。

有難う。
ブログを書くという事に慣れていませんで、自身に不備があるのは承知しています。
正直言ってブログって何なのか今でもよく分かりません。
それで、今は1年の経験値がありますので、一度全て見直そうかなと思っています。
1年前は経験値0の状態でしたので、新しく書いたら前よりもよい記事になると思います。
何事も前向きにトライしますのでまた来てね。

>正直言ってブログって何なのか今でもよく分かりません。

コメントをくださる方とどういう付き合いをするかを決めて、ブログを設定すると良いと思います。

今の展開があなたにとってつらいなら、コメントを受け付けない設定にし、フリーメールのアドレスを公開して意見を受け付ける手もあります。

やり取りをコメント欄からメールに切り替えることによりやり取りが見えなくなりますので、寄せられたコメントに対するコメントやあなたの回答に対するコメントはできなくなります。要するにお祭り騒ぎはなくなります。

反面、意見が重複しますので誠意をもって対応する必要があります。



「どちらが正しい」に執着することなく、時間を割いてくれたことに感謝できるようになれたなら、もう荒れないと思いますよ。

Jittaさんが、アクセス禁止にするかなぁ。
疑問です。>Jittaさん

インドリさんは「アクセス禁止になっている」とは言ってませんよ。
(重たくて)アクセス出来なかっただけかもしれません。

Re: タイトルなし

> インドリさんは「アクセス禁止になっている」とは言ってませんよ。
> (重たくて)アクセス出来なかっただけかもしれません。

アクセス権限がないといわれたので、多分わんくま同盟にアクセスできないのだと思います。

Re: タイトルなし

> 「どちらが正しい」に執着することなく、時間を割いてくれたことに感謝できるようになれたなら、もう荒れないと思いますよ。

有難う。
この展開が辛いというわけではないのですが、
ブログってこんなに手間かかるとは思わなかったというのが正直な感想です。
仕事ならば私も一語一句間違わないように警戒して書きますが、
まさかブログでここまでとやかく言われるとは思いませんでした。
まるで女の職場です(笑)
この状態では息抜きになりません。仕事が増えたような憂鬱な気分です。
でもまぁ、これもまた人生において貴重な体験だと思いますのでめげずに頑張ります。

>アクセス権限がないといわれたので、多分わんくま同盟にアクセスできないのだと思います。

そうでしたか。ちょっと勘違いしたようです。
でも、制限するって事はIPが判らないと出来ないですよね。
そりゃアクセスログ見ればIPは判りますが、それだけじゃ個人の特定は無理ですよね。
書き込みをすれば特定は可能でしょうけど。

>まさかブログでここまでとやかく言われるとは思いませんでした。

最初からどうでもいいようなブログでは誰も何も言いません。
期待している(していた)ブログだから辛口になって言ってるのではないでしょうか?
初心者はブログの記事を鵜呑みにしてしまい、コピペでソースを使ったりします。
なので、ブログであっても間違いは無い(少ない)ほうが良いと思いますけど。

Re: タイトルなし

> なので、ブログであっても間違いは無い(少ない)ほうが良いと思いますけど。

確かにないほうがいいですね。
それでその手のプログラムを作ろうと思ったのですが、それ自体に色々言われました(笑)
間違いを減らそうとしたらケチつけられたのには驚かされました。
でも、間違いは無かった方がいいと思いますので、後でサクッとブログ補助ツール作ります。
これでつまらない間違いはほぼなくなると思います。

> なので、ブログであっても間違いは無い(少ない)ほうが良いと思いますけど。

確かにないほうがいいですね。
後でサクッとブログ補助ツール作ります。
これでつまらない間違いはほぼなくなると思います。

---------------------------------------- 添削終わり

上記で問題ありますか?
※削った部分(言い訳じみた発言、余計な一言)が火種になりえる部分

削った部分を書きたい気持ちはわからないわけではないですが、ここを改善しないとまた荒れますよ。

Re: タイトルなし

> 削った部分を書きたい気持ちはわからないわけではないですが、ここを改善しないとまた荒れますよ。

仰るとおりです。

> Jitta さんへ
> 書き方でかちんときたけど確かにミスはありました。
> 申し訳ございませんでした。
謝る相手が違うと思います。
http://indori.blog32.fc2.com/blog-entry-206.html
こちらの(あるいはVBバージョンにコメントされている)yudaさんこそ、謝る相手ではないでしょうか。
プロフィール

インドリ

Author:インドリ
みなさん、はじめまして、
コンニチハ。

ボクは、無限の夢(infinity dream)を持つネタ好きな虹色の鳥インドリ(in dre)です。
色々な情報処理技術を啄ばむから楽しみにしてね。

http://twitter.com/indori
は別人による嫌がらせ行為です。
私とは関係ないので注意して下さい。
次はなりすましブログなどをするかもしれませんが、ここ以外でブログをするつもりがないので、ここ以外にインドリのブログがあったとしても無視してください。


何度言っても分からない人がいるので、ここにコメント欄へ書き込むときの注意事項を書きます。


一、社会人としてのマナーをわきまえましょう。
一、妄想に基づく書き込みを止めてください。
一、暴言の類は書かないで下さい。
一、某誹謗中傷サイトの書き込みは彼らの妄想に基づく書き込みですから無視して、ここへ書き込まないで下さい。
一、コメント書く前に他のコメントよく読んでから行って下さい。
一、言いがかかり等の行為を禁止します。
一、その他常識的に考えて迷惑なコメントはしないで下さい。


以上のルールを守れない人のコメントは削除します。



利用上の注意
ここに紹介してある文章およびプログラムコードは正確であるように心がけておりますが、内容を保証するものではありません。当サイトの内容によって生じた損害については、一切の責任を負いませんので御了承ください。


執筆したCodeZineの記事


【VB.NETで仮想CPUを作ろう】

  1. VB.NETで仮想CPUを作ろう
  2. レジスタの実装
  3. 仮想CPUのGUI化
  4. テストドライバの改良
  5. CPUの基礎動作の実装
  6. MOV命令の実装
  7. ADD命令実装
  8. SUB命令実装
  9. INC命令&DEC命令の実装と命令長
  10. MLU命令の実装とModR/Mについて
  11. DIV命令の実装とイベント設計について
  12. 機械語駆動式 関数電卓を作ろう!
  13. 機械語駆動式 関数電卓を作ろう! 解答編(前半)
  14. 機械語駆動式 関数電卓を作ろう! 解答編(後半)


【仮想ネットワーク実装でTCP/IPを学ぼう】
  1. TCP/IPの基礎と勘所
  2. ネットワークアクセス層の勘所
  3. インターネット層の勘所
  4. トランスポート層の勘所
  5. アプリケーション層の勘所
  6. セキュリティの基礎と仮想ネットワークの仕様
  7. GDI+と独自プロトコルの定義



【並列化】
インテル Parallel Studioを使って並列化プログラミングを試してみた
並列プログラミングの効率的なデバッグを実現する「Parallel Inspector」


【TBBシリーズ】
  1. インテル スレッディング・ビルディング・ブロックの概要
  2. インテルTBBから学ぶループの並列化
  3. スレッドセーフとインテルTBBのコンテナ
  4. インテルTBBのスレッドクラス


【OpenMPシリーズ】
  1. OpenMPの基礎構文
  2. OpenMPの実行時ライブラリと並列ループ
  3. OpenMPのメモリモデルとfork- joinモデル

最近の記事
最近のコメント
月別アーカイブ
カテゴリ
Ada (9)
COBOL (5)
C (9)
C++ (11)
C# (370)
D (25)
Java (8)
Perl (1)
Ruby (14)
PHP (2)
Boo (2)
Cobra (2)
LISP (6)
F# (33)
HTML (0)
XHTML (0)
CSS (0)
XML (0)
XSLT (0)
Scala (4)
WPF (0)
WF (2)
WCF (0)
LINQ (4)
MONO (5)
Linux (0)
MySQL (0)
ブログ内検索
リンク
最近のトラックバック
RSSフィード
ブロとも申請フォーム

この人とブロともになる

QRコード
FC2カウンター