中の技術日誌ブログ

C#とC++/CLIと
VBと.NETとWindowsで戯れる
 

目次

Blog 利用状況

ニュース

自己紹介

大阪でソフトウェアエンジニアをやっています。
お仕事大募集中です。
記事執筆とか、助言依頼とかでも何でもどうぞ(*^_^*)
似顔絵 MSMVPロゴ
MSMVP Visual C# Since 2004/04-2009/03
MCPロゴ
070-316
RSS feed meter for http://blogs.wankuma.com/naka/

記事カテゴリ

書庫

日記カテゴリ

00-整理

01-MSMVP

インスタンスメソッドとスタティックメソッド

まずはこのコードを見てみてください。

using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1 {
  class Program {
    static void Main(string[] args) {
      for (int i = 0; i < 999999; i++) {
        testclass aa = new testclass();
        aa.method("XXXXX");
      }
      for (int i = 0; i < 999999; i++) {
        testclass.smethod("XXXXX");
      }
    }
  }
  class testclass {
    public string method(string val) {
      return val.Trim();
    }
    public static string smethod(string val) {
      return val.Trim();
    }
  }
}

なんてことはない処理をインスタンスメソッドで呼んだ場合と、スタティックメソッドで読んだ場合の違いを表しています。
特にTrim()を行う意味はありません。

このインスタンスを呼び出すときと、スタティックを呼び出すときのコスト差(うちのノートマシン調べ)はどれくらいあるでしょうか?

Visual Studioのパフォーマンス機能で調べた結果がコレです。

インスタンスメソッド
ConsoleApplication1.testclass.method(string) 300.211083
ConsoleApplication1.testclass..ctor() 117.173502
System.Object..ctor() 65.999618
合計 483.3842
スタティックメソッド
ConsoleApplication1.testclass.smethod(string) 128.153829

実に全体で3.7倍
直接呼び出すメソッドだけ比べても約2.3倍

.NETのBCL(ベースクラスライブラリ)を見ていてもわかるように、パラメータと戻り値だけですべてが語れるメソッドはstaticメソッドにするべきです。

コード分析機能を有効にしてもこの問題は指摘されます。

ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VSENT.v80.ja/dv_vsetsa03/html/743f0af7-41d1-4852-8d97-af0688b31118.htm

http://msdn2.microsoft.com/ja-jp/library/ms245046.aspx

オブジェクト指向は決してパフォーマンス性向が良いとはいえません。

オブジェクト的に正しくないとかを振り回すだけでは融通が利かないだけでなく、パフォーマンス面で取り返しのつかない事態も想定できます。

#某ねっとみたいに・・・

当然DataSetなんかのように至れり尽くせりのものと、ミニマムプランで自作したクラスのパフォーマンスを比べたら10倍から開きがついてもおかしくはありません。

何事にも光と闇あり。

#Visual Studioのパフォーマンス計測ソフトはなかなかいいです。是非使ってみてください。

投稿日時 : 2006年8月30日 18:00

コメントを追加

# re: インスタンスメソッドとスタティックメソッド 2006/08/30 20:00 囚人

private メソッドは実際 static で済む事が多いので static にしたりしますが、あんまり几帳面にはしていませんでしたね。
vtbl を見ないからある程度は効率いいかな?ぐらいには考えてましたが。

# re: インスタンスメソッドとスタティックメソッド 2006/08/31 11:34 黒龍

ちょっと試してみたのですが通常のインスタンスだと最適化がかかれば差が出ないケース(インライン展開される)可能性がありますね。MarshalByRefObjectからの派生クラスであれば上記内容が当てはまるのでなるべくスタティック化するほうがよさそうですね。

# re: インスタンスメソッドとスタティックメソッド 2006/08/31 11:37 黒龍

> MarshalByRefObjectからの派生クラスであれば上記内容・・・
最適化前提なのでそれ以上(インスタンスメソッドのみインライン展開が抑制されるので・・・)ですね。すみませんでした。

# re: インスタンスメソッドとスタティックメソッド 2006/09/12 9:30 しゅんすけ

インスタンスメソッドを呼ぶ場合には、インスタンスの生成コストが追加されていますよね。あらかじめインスタンスを生成しておいて、ループでメソッドを呼ぶだけならスタティックメソッドよりも速くなると思います。単純にスタティックにするのではなく、状況に応じて使い分ける必要があると感じています。

# re: インスタンスメソッドとスタティックメソッド 2006/09/12 9:33 中博俊

メソッド呼び出しだけ比較してください。
vtableがある以上早くはなりませぬ。

# re: インスタンスメソッドとスタティックメソッド 2006/11/21 14:14 通りすがりの名無しですが

亀レスですが・・・・
ループの中にインスタンス生成入れちゃまずいでしょ。

# re: インスタンスメソッドとスタティックメソッド 2006/11/21 20:35 NAKA Hirotoshi.

ループしているのは計測精度を上げるためですので、これでいいです。
1つのメソッドを呼ぶときに意味なくインスタンスメソッドにするとコンストラクタや、メソッド呼び出しだけでも損をするという意味です。

タイトル  
名前  
URL
コメント