追記
以下、パフォーマンスのみについて言及しています。
本記事を書いた後、それ以外のNSLogとprintlnの違いに気付きつつ放置していましたが、この記事のAnswerがすごくよくまとまっていたので貼っておきます。
Swift: print() vs println() vs NSLog() - Stack Overflow
本文
どうしてSwiftでは既存のNSLog
に加えて、println
が増えたのだろう?
基本的にprintln
使うべきな雰囲気は感じるけど、実際にメリットは?と思って調べました。
一つはジェネリクス使って定義されているので、文字列以外も気にせずに突っ込めるところだと思います。
func println<T>(object: T)
FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
で、ここからが本題です。
遅いと悪評高いNSLog
でしたが、もしかしたらそれも解決されている?と思って測ってみました。
※Xcode6 beta6の結果です
let now = NSDate().timeIntervalSince1970
for i in 0...10000 {
println("hoge") // NSLog("hoge")でも試した
}
let elapsed = NSDate().timeIntervalSince1970 - now
println("elapsed: \(elapsed)")
シミュレーターで試したところ手元の環境では下記のような結果で、10倍くらい高速でした(実機でもほぼ同じでした)
所要時間 | |
---|---|
println |
0.2秒前後 |
NSLog |
2.3秒前後 |
じゃあObjective-Cでも使えるようにしようと思って何となくそれっぽいのを作成。
@objc
class Util {
class func NSLog(message: String) { // ジェネリクス使うとObjective-Cから見えない
println(message)
}
}
+(void)loopPrint {
NSTimeInterval now = [NSDate date].timeIntervalSince1970;
for (NSUInteger i = 0; i < 10000; i++) {
[Util NSLog:@"hoge"];
}
NSTimeInterval elapsed = [NSDate date].timeIntervalSince1970 - now;
[Util NSLog:[NSString stringWithFormat:@"elapsed: %f", elapsed]];
}
Objective-CでSwiftコードを挟んで実行しても10倍高速の同様の結果になりました。(呼び出しコスト分、少し時間かかるかな?という感じでしたが)
そして、ここまで書いた後に気づきましたが、単に速くしたいなら、以下のようなものを定義でも良いですね。
こちらもprintln
と同じかprintf
の方が若干速かったです。
+(void)NSLog2:(NSString*)message {
printf("%s\n", [message UTF8String]);
}
// あるいは
#define NSLog2(message) printf("%s\n", [(message) UTF8String])
と、Objective-Cへの横展開はprintln
使わなくても良いじゃんと自己完結しましたが、とりあえず上で書いたprintln
版とほぼ同じ結果だったので、println
は良く出来てますね。