トップ回答者
クラスに属性を付加した時のビルド時間への影響度は?

質問
-
お世話になります。
環境はVS2010、ASP.NET 4です。
現在、PostSharpを使って既存のシステムにメソッド実行のロギング機能をつけようとしています。
まずは検証ということで、全てのクラスに適用してみました。
アスペクトの織り込みはビルド時ですので、当然ビルド時間が増大しますが(約5倍になりました)
条件付きコンパイルシンボルで SkipPostSharp を指定しても、PostSharp不使用時の2倍はかかります。
普段の開発時はロギングが不要なので、SkipPostSharpしておけばいいのですが、
それでも2倍かかってしまうのは辛いです。
全クラス(全メソッド)に適用、というのがそもそも無茶な話なのでしょうが、
念のため原因の切り分けをしようとしています。
そこで質問です。
PostSharpでアスペクトを適用するクラスやメソッドには、属性を付加する必要がありますが、
PostSharp云々無関係に、属性を付加しただけでもビルド時間に大きな影響があるのでしょうか?
なお、今回の検証では1000を超えるクラスに対して属性を付加しました。
どなたかご存知の方、よろしくお願いします。
回答
-
属性の付与判定と、付与に必要な時間は当然かかると思います。
以下は個人的な感想ですが、
前者は、CondtionalAttribute の判定で、条件付きコンパイルに対応した属性の場合に発生するコストです。コンパイラは ConditionalAttribute が付与された属性は、その属性を付与するかどうかを毎回判定しなければなりません。これは、小さいものの無視できない程度のコストになることが容易に想像されます。
後者は、属性を実際に付与するためにかかるコストです。こちらはコンストラクタとプロパティに渡されている値のシリアライズ処理になりますが、文字列や数値程度であれば、通常のソースコードが1行増えている程度の時間で済むので、(1~3行程度のメソッドが大量にあるとかでもないかぎり)ソースコードの規模に比して比較的小さく無視できるレベルではないかと想像します。
- 回答としてマーク femp 2011年7月23日 3:49
-
何の時間が増加しているのか、正確に測定するのが近道かと。そして、その処理が必要なのかどうかの判断も。
ASP.NETは本来、オンデマンドで、つまりWebブラウザー等からアクセスがあった際にその場でコンパイルします。完成したらパフォーマンス向上のために事前コンパイルするのもありですが。
PostSharpを使ったことがないのでどのように実装されているのかわかりませんが、通常のコンパイル後にPostSharp独自の処理が走っていてそれが時間を要しているのではありませんか? もしそうなら、その部分の処理だけ停止させれば通常のコンパイル時間で済むでしょう。
C#本来のコンパイル処理(突き詰めればcsc.exeのやること)は属性が1000ヶ所に付与されようがたいした時間差になるとは思えません。本題とずれますが、クラス1000個というのは設計が気になりますw
- 回答としてマーク femp 2011年7月23日 3:49
すべての返信
-
属性の付与判定と、付与に必要な時間は当然かかると思います。
以下は個人的な感想ですが、
前者は、CondtionalAttribute の判定で、条件付きコンパイルに対応した属性の場合に発生するコストです。コンパイラは ConditionalAttribute が付与された属性は、その属性を付与するかどうかを毎回判定しなければなりません。これは、小さいものの無視できない程度のコストになることが容易に想像されます。
後者は、属性を実際に付与するためにかかるコストです。こちらはコンストラクタとプロパティに渡されている値のシリアライズ処理になりますが、文字列や数値程度であれば、通常のソースコードが1行増えている程度の時間で済むので、(1~3行程度のメソッドが大量にあるとかでもないかぎり)ソースコードの規模に比して比較的小さく無視できるレベルではないかと想像します。
- 回答としてマーク femp 2011年7月23日 3:49
-
何の時間が増加しているのか、正確に測定するのが近道かと。そして、その処理が必要なのかどうかの判断も。
ASP.NETは本来、オンデマンドで、つまりWebブラウザー等からアクセスがあった際にその場でコンパイルします。完成したらパフォーマンス向上のために事前コンパイルするのもありですが。
PostSharpを使ったことがないのでどのように実装されているのかわかりませんが、通常のコンパイル後にPostSharp独自の処理が走っていてそれが時間を要しているのではありませんか? もしそうなら、その部分の処理だけ停止させれば通常のコンパイル時間で済むでしょう。
C#本来のコンパイル処理(突き詰めればcsc.exeのやること)は属性が1000ヶ所に付与されようがたいした時間差になるとは思えません。本題とずれますが、クラス1000個というのは設計が気になりますw
- 回答としてマーク femp 2011年7月23日 3:49
-
回答ありがとうございます。
確かに、まずはサンプル作って実験してみろって話ですね、申し訳ありません。
理論的根拠が分かれば知りたくて、先に質問してしまいました。
試しに単純なpublicメソッドを10個持つクラスを1000個作って、
空の属性(Attribute継承しただけ)を用意し、その有無でビルド時間を比較しました。
当然PostSharpは使っていません。
結果、おおよそ2倍(属性なし3秒→属性あり7秒ぐらい)の差が出ました。
属性付けただけでも結構影響があるんですね・・・
> 本題とずれますが、クラス1000個というのは設計が気になりますw
ですよね・・・
何年も前から販売しているASP.NETアプリのパッケージソフトなんですが、
機能追加、追加、追加で本体のWebアプリプロジェクトが肥大化してしまっています。
他のクラスライブラリはそうでもないんですが。
やっぱこれ、一般的に見て「多すぎる」量なんですね・・・
他の現場を見たことがないのでよく分からなかったのですが。