LoginSignup
46
43

More than 5 years have passed since last update.

SwiftのprintlnはNSLogの10倍くらい高速

Last updated at Posted at 2014-08-21

追記

以下、パフォーマンスのみについて言及しています。
本記事を書いた後、それ以外の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の結果です

10000回ループ.swift
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は良く出来てますね。

46
43
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
43