2014年06月11日

C#で実行時間の測定

   このエントリーをはてなブックマークに追加 Clip to Evernote
どう書く?orgに感謝を込めて」シリーズ その15

■問題  (出題者:にしお さん)

ある比較的重たい処理をする関数「func」があるとします。 この関数を呼び出して、その実行にかかった時間を表示する関数「profile」を書いてください。 言語として可能であれば、「profile」が「func」と同じ引数で呼び出せるようにしてください。


なかなか面白い問題ですね。
ここでは、func1, func2 の2つのメソッドを呼び出し、それぞれの時間計測をするコードを書いています。
C#らしく profile関数ではなく、Profileクラスを作成してみました。 引き数の数も自由ですし、戻り値も返せます。 

■C#で書いたコード
using System;
using System.Reflection;
using System.Diagnostics;

namespace Doukaku.Org {
    class Program {
        static void Main(string[] args) {
            {
                var profile = new Profile(new Func<string, int>(func1));
                var r = profile.Call("Hello world");
                Console.WriteLine("結果={0}",r);
                Console.WriteLine("実行時間={0}",profile.Elapsed);
            }
            Console.WriteLine();
            {
                var profile = new Profile(new Func<int, int, string>(func2));
                var r = profile.Call(123, 456);
                Console.WriteLine("結果={0}", r);
                Console.WriteLine("実行時間={0}", profile.Elapsed);
            }
        }

        static int func1(string s) {
            Console.WriteLine(s);
            return s.Length;
        }

        static string func2(int n1, int n2) {
            Console.WriteLine(n1);
            Console.WriteLine(n2);
            return (n1 + n2).ToString();
        }
    }

    // 時間計測クラス
    class Profile {
        private MethodInfo methodInfo;

        // コンストラクタ
        // 引き数には、時間計測したいメソッドを渡す。
        public Profile(Delegate func) {
            this.methodInfo = func.Method;
        }

        // コンストラクタで指定したメソッドを呼び出し、その時間を計測する。
        // 計測時間は、Elapsedプロパティにセットする。
        public object Call(params object[] args) {
            Stopwatch sw = Stopwatch.StartNew();
            var r = methodInfo.Invoke(null, args);
            Elapsed = sw.Elapsed;
            return r;
        }

        public TimeSpan Elapsed { get; private set; }
    }
}
  

Posted by gushwell at 22:00Comments(0)TrackBack(0)

2014年06月08日

C#でメソッドの一覧と呼び出し

   このエントリーをはてなブックマークに追加 Clip to Evernote
どう書く?orgに感謝を込めて」シリーズ その14

■問題 (出題者:にしお さん)

「ある与えられたオブジェクトtargetのメソッドのうち、 "test_"で始まるものをすべて呼びだす」というコードを書いてください。 引数に関しては都合のいいように仮定して構いません(全部0個、など)。
 メソッドという概念がない言語の場合は、 「複数の関数への参照を持っているようなオブジェクト(たとえばパッケージとかモジュールとか)から"test_"で始まる関数をすべて呼び出す」と読み替えても構いません。


.NETなので、Test_ (先頭大文字)で始まるメソッドとしました。 この例では、面倒なので、引き数は0個としています。

■C#で書いたコード

using System; using System.Linq; namespace Doukaku.Org { class Program { static void Main(string[] args) { // Sample クラスの Test_xxxx メソッドをすべて呼び出す。 Sample sample = new Sample(); sample.GetType().GetMethods() .Where(m => m.Name.StartsWith("Test_")) .ForEach(m => m.Invoke(sample, null)); } } class Sample { public void Test_Bar() { Console.WriteLine("Test_Bar"); } public void Test_Foo() { Console.WriteLine("Test_Foo"); } public void Test_Baz() { Console.WriteLine("Test_Baz"); } public void Hoge() { Console.WriteLine("Hoge"); } } }
  
Posted by gushwell at 21:30Comments(0)TrackBack(0)

2010年09月26日

現在実行中のメソッド名を得る

   このエントリーをはてなブックマークに追加 Clip to Evernote
System.Reflection.MethodBase.GetCurrentMethod()は、現在実行中のメソッドを表す MethodBase オブジェクトを返します。

Name プロパティで、メソッド名を取得でき、DeclaringType はこのメンバーを宣言しているクラスを取得できます。

以下、C#の簡単な例です。


結果は、

button1_Click
Sample.Form1

と表示されます。
MethodBaseを受け取るメソッドを作成し、MethodBase.GetCurrentMethod() を引数に渡してあげれば、簡易トレースメソッドが出来そうです。   
Posted by gushwell at 23:19Comments(0)TrackBack(0)

2010年07月06日

あるオブジェクトが派生型かどうかを知りたい

   このエントリーをはてなブックマークに追加 Clip to Evernote


というクラスがあった時に、
あるオブジェクトの型が、BaseClassの派生型かどうかを調べるコードをC#で書きたい場合がたまにあります。


だと、obj が BaseClassのインスタンスでも、この if 文が成り立ってしまうので宜しくないです。


だと、ちょっとダサい。
そんなときは、そのものずばりのメソッド IsSubclassOf を使います。

  
Posted by gushwell at 23:01Comments(0)TrackBack(1)

2010年01月31日

エントリ・ポイントを含むアセンブリ(Assemblyオブジェクト)を取得

   このエントリーをはてなブックマークに追加 Clip to Evernote
以下は、現在実行されているアセンブリのバージョンを得るコードです。


GetName() というメソッド名が紛らわしいんですよね。
GetName()で返るのは、文字列ではなく、System.Reflection.AssemblyName クラスの インスタンスです。

GetExecutingAssembly の代わりに、GetEntryAssembly を使えば、 エントリポイント(Mainメソッド)を含むアセンブリの情報を取得できます。
クラスライブラリ側で、実行中のexeのアセンブリ情報を利用したい場合に使えます。
以下のコードは、バージョン情報を得るコードです。


もちろん、そのパス名や、アセンブリ表示名も取得できます。


  
Posted by gushwell at 23:39Comments(0)TrackBack(0)