Created
April 22, 2010 01:07
-
-
Save faultier/374671 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.swp | |
.DS_Store | |
*.o | |
array_map | |
thread_test | |
concurrent | |
string_benchmark |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import "NSArrayMap.h" | |
int main(int argc, char **argv) { | |
NSAutoreleasePool *pool = [NSAutoreleasePool new]; | |
NSArrayMapper block = ^ id (id item) { | |
return [NSString stringWithFormat:@"My name is %@ since yesterday.",item]; | |
}; | |
NSArray *array = [NSArray arrayWithObjects:@"Sato",@"Ito",@"Kato",@"Naito",@"Saemonsaburo",nil]; | |
NSLog(@"\n%@", array); | |
NSLog(@"\n%@", [array mapUsingBlock:block]); | |
[pool drain]; | |
return 0; | |
} | |
// vim: ft=objc ff=unix fenc=utf-8 ts=2 sts=2 sw=2 expandtab : |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# coding: utf-8 | |
require 'pp' | |
array = %w(ひたぎ 真宵 駿河 撫子 翼) | |
pp array | |
pp array.map {|item| | |
"#{item}が好きすぎて生きるのが辛い" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
typedef void (^Benchmarker)(void); | |
typedef enum { | |
BenchmarkFormatTime, | |
BenchmarkFormatCompare, | |
} BenchmarkFormat; | |
@interface Benchmark : NSObject | |
{ // attributes | |
@private | |
NSUInteger iterations_; | |
BenchmarkFormat format_; | |
NSMutableDictionary *targets_; | |
} | |
@property (assign) NSUInteger iterations; | |
@property (assign) BenchmarkFormat format; | |
@property (readonly) NSDictionary *targets; | |
+ (void)benchmarkWithTargets:(NSDictionary *)targets; | |
- (id)initWithTargets:(NSDictionary *)targets iterations:(NSUInteger)iterations; | |
- (id)initWithTargets:(NSDictionary *)targets; | |
- (void)setTarget:(Benchmarker)block forName:(NSString *)name; | |
- (void)benchmark; | |
- (void)clear; | |
@end | |
// vim: set ft=objc ff=unix fenc=utf-8 ts=2 sts=2 sw=2 expandtab : |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "Benchmark.h" | |
#define _FloatToNumber(f) [NSNumber numberWithFloat:f] | |
static NSUInteger _defaultIterations = 10000; | |
@implementation Benchmark | |
@synthesize iterations = iterations_; | |
@synthesize format = format_; | |
@synthesize targets = targets_; | |
+ (void)benchmarkWithTargets:(NSDictionary *)targets { | |
Benchmark *b = [[Benchmark alloc] initWithTargets:targets]; | |
[b benchmark]; | |
[b release]; | |
} | |
- (id)initWithTargets:(NSDictionary *)targets iterations:(NSUInteger)iterations { | |
if ((self = [super init])) { | |
iterations_ = iterations; | |
format_ = BenchmarkFormatTime; | |
targets_ = [targets retain]; | |
} | |
return self; | |
} | |
- (id)initWithTargets:(NSDictionary *)targets { | |
return [self initWithTargets:targets iterations:_defaultIterations]; | |
} | |
- (id)init { | |
return [self initWithTargets:[NSMutableDictionary dictionary] iterations:_defaultIterations]; | |
} | |
- (void)dealloc { | |
[targets_ release]; | |
[super dealloc]; | |
} | |
- (void)setTarget:(Benchmarker)block forName:(NSString *)name { | |
[targets_ setObject:block forKey:name]; | |
} | |
- (void)benchmark { | |
NSMutableDictionary *results = [NSMutableDictionary dictionary]; | |
for (id key in [targets_ keyEnumerator]) { | |
Benchmarker bench = (Benchmarker)[targets_ objectForKey:key]; | |
__block NSTimeInterval total = 0; | |
__block NSTimeInterval max = 0; | |
__block NSTimeInterval min = 0; | |
void (^job)(void) = ^{ | |
NSAutoreleasePool *pool = [NSAutoreleasePool new]; | |
NSDate *d = [NSDate date]; | |
bench(); | |
NSTimeInterval time = [[NSDate date] timeIntervalSinceDate:d]; | |
total += time; | |
max = (max > time) ? max : time; | |
min = (min > 0 && min < time) ? min : time; | |
[pool drain]; | |
}; | |
NSUInteger i = self.iterations; | |
while (i--) { | |
job(); | |
} | |
NSTimeInterval avg = total / self.iterations; | |
NSArray *res = [NSArray arrayWithObjects: | |
_FloatToNumber(total), | |
_FloatToNumber(max), | |
_FloatToNumber(min), | |
_FloatToNumber(avg), | |
nil]; | |
[results setObject:res forKey:key]; | |
} | |
NSUInteger keyLen = 0; | |
for (NSString *key in [results keyEnumerator]) { | |
keyLen = ([key length] > keyLen) ? [key length] : keyLen; | |
} | |
NSString *format = [NSString stringWithFormat:@"%%-%d%s", (keyLen+1), "s"]; | |
NSArray *keys = [results keysSortedByValueUsingComparator: | |
^(id a, id b) { return [[(NSArray *)a objectAtIndex:0] compare:[(NSArray *)b objectAtIndex:0]]; } | |
]; | |
switch (self.format) { | |
case BenchmarkFormatTime: | |
printf([[NSString stringWithFormat:@"%%-%d%s %%10s %%10s %%10s %%10s\n", (keyLen+1), "s"] UTF8String], | |
"", | |
"total", | |
"max", | |
"min", | |
"avg"); | |
[keys enumerateObjectsUsingBlock: | |
^(id key, NSUInteger idx, BOOL* stop) { | |
NSArray *r = (NSArray *)[results objectForKey:key]; | |
printf([format UTF8String], [key UTF8String]); | |
for (NSNumber *t in r) { | |
printf(" % 3.7f", [t floatValue]); | |
} | |
puts(""); | |
} | |
]; | |
break; | |
case BenchmarkFormatCompare: | |
[keys enumerateObjectsWithOptions:NSEnumerationReverse usingBlock: | |
^(id key, NSUInteger idx, BOOL* stop) { | |
NSTimeInterval r = [[(NSArray *)[results objectForKey:key] objectAtIndex:0] floatValue]; | |
printf([format UTF8String], [key UTF8String]); | |
printf("%7.0f/s", self.iterations * (1 / r)); | |
[keys enumerateObjectsWithOptions:NSEnumerationReverse usingBlock: | |
^(id key2, NSUInteger idx2, BOOL* stop2) { | |
if ([key2 isEqualToString:key]) { | |
printf(" ---"); | |
} | |
else { | |
NSTimeInterval r2 = [[(NSArray *)[results objectForKey:key2] objectAtIndex:0] floatValue]; | |
float comp = ((r2 / r - 1.00) * 100); | |
printf(" %6.0f%%", comp); | |
} | |
} | |
]; | |
puts(""); | |
} | |
]; | |
break; | |
} | |
} | |
- (void)clear { | |
[targets_ release]; | |
targets_ = [[NSMutableDictionary alloc] init]; | |
} | |
@end | |
// vim: set ft=objc ff=unix fenc=utf-8 ts=2 sts=2 sw=2 expandtab : |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
void testSequential(unsigned int times, dispatch_block_t block) { | |
unsigned int i; | |
for (i = 0; i < times; i++) { | |
block(); | |
} | |
} | |
void testDispatchAsync(unsigned int times, dispatch_block_t block) { | |
dispatch_group_t group = dispatch_group_create(); | |
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); | |
unsigned int i; | |
for (i = 0; i < times; i++) { | |
dispatch_group_async(group, queue, block); | |
} | |
dispatch_group_wait(group, DISPATCH_TIME_FOREVER); | |
} | |
void testOperation(unsigned int times, dispatch_block_t block) { | |
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; | |
unsigned int i; | |
for (i = 0; i < times; i++) { | |
[queue addOperationWithBlock:block]; | |
} | |
[queue waitUntilAllOperationsAreFinished]; | |
} | |
int main(int argc, char **argv) { | |
NSAutoreleasePool *pool = [NSAutoreleasePool new]; | |
dispatch_block_t block = [[^{ | |
NSLog(@"あと0.25秒だけ寝させてー"); | |
[NSThread sleepForTimeInterval:0.25]; | |
// NSLog(@"%@", [NSThread currentThread]; | |
} copy] autorelease]; | |
// NSLog(@"%@", [NSThread currentThread]); | |
NSDate *d1, *d2, *d3; | |
NSTimeInterval t1, t2, t3; | |
NSLog(@"----- start sequential -----"); | |
d1 = [NSDate date]; | |
testSequential(20, block); | |
t1 = [[NSDate date] timeIntervalSinceDate:d1]; | |
NSLog(@"------ end sequential ------"); | |
NSLog(@"--- start dispatch async ---"); | |
d2 = [NSDate date]; | |
testDispatchAsync(20, block); | |
t2 = [[NSDate date] timeIntervalSinceDate:d2]; | |
NSLog(@"---- end dispatch async ----"); | |
NSLog(@"----- start operation ------"); | |
d3 = [NSDate date]; | |
testOperation(20, block); | |
t3 = [[NSDate date] timeIntervalSinceDate:d3]; | |
NSLog(@"------ end operation -------"); | |
puts(""); | |
NSLog(@"sequential %f sec", t1); | |
NSLog(@"dispatch async %f sec", t2); | |
NSLog(@"operation %f sec", t3); | |
[pool drain]; | |
return 0; | |
} | |
// vim: ft=objc ff=unix fenc=utf-8 ts=2 sts=2 sw=2 expandtab : |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# coding: utf-8 | |
def do_sequential(n, f) | |
n.times do | |
f.call | |
end | |
end | |
def do_thread(n, f) | |
n.times do | |
Thread.new { f.call } | |
end | |
(ThreadGroup::Default.list - [Thread.current]).each{|th| th.join } | |
end | |
b = lambda { | |
puts "0.25秒後から本気出す" | |
sleep 0.25 | |
} | |
puts "----- start sequential -----" | |
t1 = Time.now | |
do_sequential 20, b | |
t1 = Time.now - t1 | |
puts "------ end sequential ------" | |
puts "------- start thread -------" | |
t2 = Time.now | |
do_thread 20, b | |
t2 = Time.now - t2 | |
puts "-------- end thread --------" | |
puts "" | |
puts "sequential #{t1} sec" | |
puts "thread #{t2} sec" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
typedef id (^NSArrayMapper)(id); | |
@interface NSArray (NSArrayMap) | |
- (NSArray *)mapUsingBlock:(NSArrayMapper)block; | |
- (NSArray *)mapUsingBlock:(NSArrayMapper)block concurrent:(BOOL)yesOrNo; | |
@end | |
// vim: ft=objc ff=unix fenc=utf-8 ts=2 sts=2 sw=2 expandtab : |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "NSArrayMap.h" | |
@implementation NSArray (NSArrayMap) | |
- (NSArray *)mapUsingBlock:(NSArrayMapper)block { | |
return [self mapUsingBlock:block concurrent:NO]; | |
} | |
- (NSArray *)mapUsingBlock:(NSArrayMapper)block concurrent:(BOOL)concurrent { | |
NSMutableArray *mapped = [self mutableCopy]; | |
void (^mapBlock)(id,NSUInteger,BOOL*) = | |
^(id item, NSUInteger idx, BOOL *stop) { | |
id obj = block(item); | |
[mapped replaceObjectAtIndex:idx withObject:obj]; | |
}; | |
if (concurrent) { | |
[self enumerateObjectsWithOptions:NSEnumerationConcurrent | |
usingBlock:mapBlock]; | |
} else { | |
[self enumerateObjectsUsingBlock:mapBlock]; | |
} | |
return [mapped autorelease]; | |
} | |
@end | |
// vim: set ft=objc ff=unix fenc=utf-8 ts=2 sts=2 sw=2 expandtab : |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# vim: set fileencoding=utf-8 filetype=ruby | |
require 'rake/clean' | |
FRAMEWORKS = %w(Foundation) | |
PROGS = %w(array_map thread_test concurrent string_benchmark) | |
CLEAN.include('*.o', PROGS) | |
task :default => :build | |
task :build => PROGS | |
file 'array_map' => %w(array_map.m NSArrayMap.o) do |t| | |
sh "gcc #{FRAMEWORKS.map{|f| "-framework #{f}"}.join(' ')} -o #{t} #{t.prerequisites.join(' ')}" | |
end | |
file 'thread_test' => %w(thread_test.m) do |t| | |
sh "gcc #{FRAMEWORKS.map{|f| "-framework #{f}"}.join(' ')} -o #{t} #{t.prerequisites.join(' ')}" | |
end | |
file 'concurrent' => %w(concurrent.m) do |t| | |
sh "gcc #{FRAMEWORKS.map{|f| "-framework #{f}"}.join(' ')} -o #{t} #{t.prerequisites.join(' ')}" | |
end | |
file 'string_benchmark' => %w(string_benchmark.m Benchmark.o) do |t| | |
sh "gcc #{FRAMEWORKS.map{|f| "-framework #{f}"}.join(' ')} -o #{t} #{t.prerequisites.join(' ')}" | |
end | |
rule '.o' => %w(.m .h) do |t| | |
sh "gcc -x objective-c -c -o #{t} #{t.source}" | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import "Benchmark.h" | |
int main(int argc, char **argv) { | |
NSAutoreleasePool *pool = [NSAutoreleasePool new]; | |
int n = 100; | |
NSString *str = @"またお前か"; | |
const char *cStr = [str UTF8String]; | |
BenchmarkFormat format = (argc > 1 && strcmp(argv[1],"--compare") == 0) ? BenchmarkFormatCompare : BenchmarkFormatTime; | |
Benchmarker b1 = [[^{ | |
size_t len = strlen(cStr) - 1; | |
char *buff = (char *)malloc((len * n + 1) * sizeof(char)); | |
buff[0] = '\0'; | |
unsigned int i = n; | |
while (i--) { | |
strncat(buff,cStr,len); | |
} | |
free(buff); | |
} copy] autorelease]; | |
Benchmarker b2 = [[^{ | |
NSString *buff = [NSString string]; | |
unsigned int i = n; | |
while (i--) { | |
buff = [NSString stringWithFormat:@"%@%@", buff, str]; | |
} | |
} copy] autorelease]; | |
Benchmarker b3 = [[^{ | |
NSMutableString *buff = [NSMutableString string]; | |
unsigned int i = n; | |
while (i--) { | |
[buff appendString:str]; | |
} | |
} copy] autorelease]; | |
Benchmark *bm = [Benchmark new]; | |
[bm setFormat:format]; | |
[bm setTarget:b1 forName:@"C String"]; | |
[bm setTarget:b2 forName:@"NSString"]; | |
[bm setTarget:b3 forName:@"NSMutableString"]; | |
[bm benchmark]; | |
[pool release]; | |
return 0; | |
} | |
// vim: ft=objc ff=unix fenc=utf-8 ts=2 sts=2 sw=2 expandtab : |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface Runner : NSObject { | |
} | |
- (void)run; | |
@end | |
@implementation Runner | |
- (void)run { | |
NSLog(@"あと0.25秒だけ寝させてー"); | |
[NSThread sleepForTimeInterval:0.25]; | |
//[NSThread exit]; | |
} | |
@end | |
int main(int argc, char **argv) { | |
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | |
Runner *runner = [[Runner alloc] init]; | |
unsigned int i; | |
NSLog(@"using NSThread -------------"); | |
NSMutableArray *group = [NSMutableArray array]; | |
i = 20; | |
while (i--) { | |
NSThread *t = [[NSThread alloc] initWithTarget:runner | |
selector:@selector(run) | |
object:nil]; | |
[group addObject:t]; | |
[t start]; | |
[t autorelease]; | |
} | |
for (NSThread *t in group) { | |
while ([t isExecuting]) { | |
// 本当は単に | |
// [NSThread sleepForTimeInterval:0.01]; | |
// とかしてメインスレッドで子スレッドの終了を待つだけの処理のつもり。 | |
// このコードだとRunLoopが回ってないので、 | |
// NSThreadとかNSTimerとかが動いてくれないので、 | |
// とりあえずrunUntilDateでRunLoopを回してごまかす。 | |
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; | |
} | |
} | |
puts(""); | |
NSLog(@"using NSOperationQueue -----"); | |
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; | |
i = 20; | |
while (i--) { | |
NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:runner | |
selector:@selector(run) | |
object:nil]; | |
[queue addOperation:op]; | |
[op autorelease]; | |
} | |
[queue waitUntilAllOperationsAreFinished]; | |
[queue release]; | |
[runner release]; | |
[pool release]; | |
return 0; | |
} | |
// vim: set ft=objc fenc=utf-8 ts=2 sts=2 sw=2 expandtab : |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment