Add tags

Add tags to the following comment
任意のオブジェクトに任意のメッセージを送ってその実行時間を測定するようにしてみました。
実行結果はこんな感じ。

$ ./profile                                                                                                                           
2007-11-16 02:11:49.268 profile[3982:10b] start  profiling [TestClass func:]
2007-11-16 02:11:49.274 profile[3982:10b] 一言言って1.000000秒待つことを3回繰り返すだけの簡単なお仕事です
2007-11-16 02:11:50.275 profile[3982:10b] 一言言って1.000000秒待つことを3回繰り返すだけの簡単なお仕事です
2007-11-16 02:11:51.276 profile[3982:10b] 一言言って1.000000秒待つことを3回繰り返すだけの簡単なお仕事です
2007-11-16 02:11:52.277 profile[3982:10b] finished!
2007-11-16 02:11:52.278 profile[3982:10b] process time: 3.003400 (sec)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
#import <Foundation/Foundation.h>

@interface Profiler : NSObject
{
    id target;
}
- (id)initWithObject:(id)aTarget;
- (void)setTarget:(id)aTarget;
@end

@implementation Profiler
- (id)initWithObject:(id)aTarget
{
    [super init];
    target = aTarget;
    return self;
}
- (id)init
{
    return [self initWithObject:nil];
}
- (void)setTarget:(id)aTarget
{
    target = aTarget;
    return;
}
- (void)profile:(NSInvocation *)anInvocation
{
    NSLog(@"start profiling [%@ %s]", [target className], [anInvocation selector]);
    NSDate *startTime = [NSDate date];
    [anInvocation invokeWithTarget:target];
    NSDate *endTime = [NSDate date];
    NSLog(@"finished!");
    NSLog(@"process time: %f (sec)", [endTime timeIntervalSinceDate:startTime]);
    return;
}
// メッセージ転送によって「対象の関数と同じ引数でプロファイル」を実現する
// Profilerの実装していないメッセージが来たら、
// 実行時間の計測をしつつ実際の処理はtargetに移譲
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    if ([target respondsToSelector:aSelector])
        return [target methodSignatureForSelector:aSelector];
    else
        return [super methodSignatureForSelector:aSelector];
}
- (BOOL)respondsToSelector:(SEL)aSelector
{
    if ([super respondsToSelector:aSelector])
        return YES;
    if ([self methodForSelector:aSelector] != (IMP)NULL)
        return YES;
    if ([target respondsToSelector:aSelector])
        return YES;
    return NO;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    if ([target respondsToSelector:[anInvocation selector]])
    {
        [self profile:anInvocation];
    }
    else
    {
        [super forwardInvocation:anInvocation];
    }
    return;
}
//--- メッセージ転送処理ここまで
@end

@interface TestClass : NSObject
{
    NSTimeInterval interval;
}
- (void)func:(int)times;
@end

@implementation TestClass
- (id)init
{
    [super init];
    interval = 1.0;
    return self;
}
- (void)func:(int)times
{
    int i;
    for (i = 0; i < times; i++)
    {
        NSLog(@"一言言って%f秒待つことを%d回繰り返すだけの簡単なお仕事です", interval, times);
        [NSThread sleepForTimeInterval:interval];
        // Xcode 2.x だとスレッドのスリープはこっち
        // [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:interval]];
    }
}
@end

int main(int argc, const char *argv[])
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    
    id testTarget = [TestClass new];
    Profiler *profiler = [[Profiler alloc] initWithObject:testTarget];

    //profilerに本来testTargetが受けとるはずのメッセージを送ってやる
    [profiler func:3];

    [pool release];
    return 0;
}

Add tags

The input will be splited to tags with space.

Index

Feed

Other

Link

Pathtraq

loading...