2013年1月18日金曜日

メソッドの実行時間計測ライブラリと TheWrapper



実行時間を計測したいメソッドを最初に1回登録するだけでいい。
+(void) initialize {
  AddProfiler([MyClass class], @selector(foo));
}

-(void) foo {
...
}

Running [self foo] will print:

*** Timer MyClass_foo started. ***
*** Timer MyClass_foo stopped. runtime: 1.633041 milliseconds ***

1行と短い上に記述箇所は1箇所だし、デバッグコードをメソッド内に書く必要が無いのがいい。これは良いアイディア。

内部では TheWrapper という別のライブラリを使用している。


このライブラリではメソッドの呼び出し前と後でblocksを実行できるAPIを用意している。
+(void) addWrapperto:(id) target andSelector:(SEL) selector withPreRunBlock:(void (^)(va_list args)) preRunblock;
+(void) addWrapperto:(id) target andSelector:(SEL) selector withPostRunBlock:(id (^)(id functionReturnValue, va_list args)) postRunBlock;
+(void) addWrapperto:(id) target andSelector:(SEL) selector withPreRunBlock:(void (^)(va_list args)) preRunblock andPostRunBlock:(id (^)(id functionReturnValue, va_list args)) postRunBlock;

+(void) addWrappertoClass:(Class) clazz andSelector:(SEL) selector withPreRunBlock:(void (^)(va_list args)) preRunblock;
+(void) addWrappertoClass:(Class) clazz andSelector:(SEL) selector withPostRunBlock:(id (^)(id functionReturnValue, va_list args)) postRunBlock;
+(void) addWrappertoClass:(Class) clazz andSelector:(SEL) selector withPreRunBlock:(void (^)(va_list args)) preRunblock andPostRunBlock:(id (^)(id functionReturnValue, va_list args)) postRunBlock;

+(void) removeWrapperFrom:(id) target andSelector:(SEL) selector;
+(void) removeWrapperFromClass:(Class) clazz andSelector:(SEL) selector;

このライブラリでは Objective-CのランタイムAPIを使い、指定されたメソッドの実装を前後処理を加えた関数(WrapperFunction)で置き換えている。

メソッド → オリジナル実装
  ↓
 置換
  ↓
メソッド → WrapperFunction

WrapperFunction (){
 preRunBlock実行;
 オリジナル実装実行;
 postRunBlock実行;
}

面白い。このライブラリはデバッグで色々活用できそう。

0 件のコメント:

コメントを投稿