数値 → 文字列変換
Objective-Cで、int値を文字列に変換する簡単な方法は2つくらいあります。
(たぶんもっとありますが、今回は以下の2つに絞ってみました。)
1. NSString.stringWithFormatを使う
NSString* str = [NSString stringWithFormat:@"%d", 100];
2. NSNumber#stringValueを使う
NSString* str = [[NSNumber numberWithInt:100] stringValue];
Google検索すると、1の方法がたくさん出てくるんですけど、ただ値を数字に変換したいだけなのに、書式化文字列を使うのって、直感的ではないというか、ちょっと無駄に見えてしまうのは私だけでしょうか?
実際、どちらの方が効率的なのでしょうか。
// 数値 → 文字列変換 // NSString.stringWithFormat と NSNumber#stringValue // どちらが速いか試してみた。 static const int TEST_COUNT = 300000; NSString* str; // テスト用メイン関数 int main(int argc, const char** argv) { @autoreleasepool { // Format NSDate* st1 = [NSDate date]; for (int i = 0; TEST_COUNT > i; ++ i) { str = [NSString stringWithFormat:@"%d", i]; } NSDate* ed1 = [NSDate date]; // NSNumber NSDate* st2 = [NSDate date]; for (int i = 0; TEST_COUNT > i; ++ i) { str = [[NSNumber numberWithInt:i] stringValue]; } NSDate* ed2 = [NSDate date]; // 結果表示 NSTimeInterval span1 = [ed1 timeIntervalSinceDate:st1]; NSTimeInterval span2 = [ed2 timeIntervalSinceDate:st2]; NSLog(@"Format:%lf", span1); NSLog(@"Number:%lf", span2); } }
【結果】
Format:0.220640 Number:0.316869
結構差が出ました。
私の環境では、stringWithFormatの方が高速という結果になりました。
んまあ、これは単純に、Objective-Cのメッセージ送信(他の多くの言語でいうところのメソッドコール)が1回と2回という差がそのまま出てるような気がしなくもない。
しかし、文字列と数字の連結でもないのに、書式化を使うというのは、やっぱりなんだか気持ちが悪いです。
JavaのString.valueOf(int)みたいな方が直感的だし覚えやすいと思うんですよ。
■valueOfという名のsprintf
// NSStringクラスに、valueOf(int)メソッドを追加してみた static const int TEST_COUNT = 300000; NSString* str; // 良い子のみんなはこんなことしちゃダメだぞ☆ @interface NSString(Pizza) +(NSString*)valueOf:(int)i; @end @implementation NSString(Pizza) +(NSString*)valueOf:(int)i { char buff[32] ; snprintf(buff, sizeof(buff), "%d", i); return [NSString stringWithUTF8String:buff]; } @end // テスト用メイン関数 int main(int argc, const char** argv) { @autoreleasepool { // Format NSDate* st1 = [NSDate date]; for (int i = 0; TEST_COUNT > i; ++ i) { str = [NSString stringWithFormat:@"%d", i]; } NSDate* ed1 = [NSDate date]; // NSNumber NSDate* st2 = [NSDate date]; for (int i = 0; TEST_COUNT > i; ++ i) { str = [[NSNumber numberWithInt:i] stringValue]; } NSDate* ed2 = [NSDate date]; // sprintf NSDate* st3 = [NSDate date]; for (int i = 0; TEST_COUNT > i; ++ i) { str = [NSString valueOf:i]; } NSDate* ed3 = [NSDate date]; // 結果表示 NSTimeInterval span1 = [ed1 timeIntervalSinceDate:st1]; NSTimeInterval span2 = [ed2 timeIntervalSinceDate:st2]; NSTimeInterval span3 = [ed3 timeIntervalSinceDate:st3]; NSLog(@"Format:%lf", span1); NSLog(@"Number:%lf", span2); NSLog(@"sprintf:%lf", span3); } }
【結果】
Format:0.220222 Number:0.313962 sprintf:0.082791
速くはなったけど、実際の開発でこんなことをするつもりはありません。
素直にNSString.stringWithFormat使います、はい。