私はプロジェクトオイラー#22に取り組んでおり、約9.6ミリ秒でソリューションを取得しました。これが私が持っているものです:
#import <Foundation/Foundation.h>
NSUInteger valueOfName(NSString *name) {
NSUInteger sum = 0;
for (int i = 0; i < [name length]; i++) {
unichar character = [name characterAtIndex:i];
sum += (character - 64);
}
return sum;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
NSMutableString *names = [NSMutableString stringWithContentsOfFile:[@"~/Documents/Developer/Project Euler/Problem22/names.txt" stringByExpandingTildeInPath] encoding:NSASCIIStringEncoding error:nil];
CFAbsoluteTime diskIOTime = CFAbsoluteTimeGetCurrent();
[names replaceOccurrencesOfString:@"\"" withString:@"" options:NSLiteralSearch range:NSMakeRange(0, [names length])];
NSArray *namesArray = [names componentsSeparatedByString:@","];
namesArray = [namesArray sortedArrayUsingSelector:@selector(compare:)];
// Marker 1
int totalScore = 0;
for (int i = 0; i < [namesArray count]; i++) {
NSString *name = namesArray[i];
NSUInteger sum = valueOfName(name);
NSUInteger position = i + 1;
totalScore += (sum * position);
}
// Marker 2
CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();
double timeDiff = (endTime - currentTime) * 1000;
printf("Total score: %d\n", totalScore);
printf("Disk IO Time: %fms\tTime: %fms\n", ((diskIOTime - currentTime) * 1000), timeDiff);
}
return 0;
}
良い時期ですが、複数のスレッドを使用して高速化する方法を考え始めました。クアッドコアCPUを使用すると、理論的には、名前の4分の1を別々のスレッドで処理し、そこから合計を取得できるはずです。これが私が試したことです(上記のマーカー間のコードを置き換えます):
__block int totalScore = 0;
int quarterArray = [namesArray count] /4 ;
typedef void(^WordScoreBlock)(void);
WordScoreBlock block1 = ^{
for (int i = 0; i < quarterArray; i++) {
NSString *name = namesArray[i];
NSUInteger sum = valueOfName(name);
NSUInteger position = i + 1;
totalScore += (sum * position);
}
printf("Total score block 1: %d\n", totalScore);
};
WordScoreBlock block2 = ^{
for (int i = quarterArray; i < (quarterArray * 2); i++) {
NSString *name = namesArray[i];
NSUInteger sum = valueOfName(name);
NSUInteger position = i + 1;
totalScore += (sum * position);
}
};
WordScoreBlock block3 = ^{
for (int i = (quarterArray * 2); i < (quarterArray * 3); i++) {
NSString *name = namesArray[i];
NSUInteger sum = valueOfName(name);
NSUInteger position = i + 1;
totalScore += (sum * position);
}
};
WordScoreBlock block4 = ^{
for (int i = (quarterArray * 3); i < [namesArray count]; i++) {
NSString *name = namesArray[i];
NSUInteger sum = valueOfName(name);
NSUInteger position = i + 1;
totalScore += (sum * position);
}
};
dispatch_queue_t processQueue = dispatch_queue_create("Euler22", NULL);
dispatch_async(processQueue, block1);
dispatch_async(processQueue, block2);
dispatch_async(processQueue, block3);
dispatch_async(processQueue, block4);
ただし、結果は0になりますが、時間は約1ミリ秒速くなります。
- このマルチスレッドアプローチは可能ですか?
- もしそうなら、私はそれをどのように実装しますか?