ensan-hcl / azooKey

azooKey: A Japanese Keyboard iOS Application Fully Developed in Swift
https://azookey.netlify.app/
MIT License
299 stars 16 forks source link

[Performance] `debug`を`@autoclosure`にする #208

Closed ensan-hcl closed 1 year ago

ensan-hcl commented 1 year ago

Releaseビルドでは出力しないタイプのprintとしてazooKeyではdebugを多用しているが、現在の実装は呼び出し時に引数が全て評価されるため、引数の計算自体は行われてしまう。そこで、以下のように変更することで若干高速になることを期待できる。実際軽く試したところ5%程度改善しそうだった。これを厳密に評価し、良好なら導入したい。

@_disfavoredOverload
@inlinable public func debug(_ items: Any...) {
#if DEBUG
    print(items.reduce(into: "") {$0.append(contentsOf: " \($1)")})
#endif
}

@inlinable public func debug(_ item1: @autoclosure () -> some Any) {
#if DEBUG
    print(item1())
#endif
}
@inlinable public func debug(_ item1: @autoclosure () -> some Any, _ item2: @autoclosure () -> some Any) {
#if DEBUG
    print(item1(), item2())
#endif
}
@inlinable public func debug(_ item1: @autoclosure () -> some Any, _ item2: @autoclosure () -> some Any, _ item3: @autoclosure () -> some Any) {
#if DEBUG
    print(item1(), item2(), item3())
#endif
}
@inlinable public func debug(_ item1: @autoclosure () -> some Any, _ item2: @autoclosure () -> some Any, _ item3: @autoclosure () -> some Any, _ item4: @autoclosure () -> some Any) {
#if DEBUG
    print(item1(), item2(), item3(), item4())
#endif
}
@inlinable public func debug(_ item1: @autoclosure () -> some Any, _ item2: @autoclosure () -> some Any, _ item3: @autoclosure () -> some Any, _ item4: @autoclosure () -> some Any, _ item5: @autoclosure () -> some Any) {
#if DEBUG
    print(item1(), item2(), item3(), item4(), item5())
#endif
}
@inlinable public func debug(_ item1: @autoclosure () -> some Any, _ item2: @autoclosure () -> some Any, _ item3: @autoclosure () -> some Any, _ item4: @autoclosure () -> some Any, _ item5: @autoclosure () -> some Any, _ item6: @autoclosure () -> some Any) {
#if DEBUG
    print(item1(), item2(), item3(), item4(), item5(), item6())
#endif
}
ensan-hcl commented 1 year ago

Swift5.9でvariadic genericsが来たらこれも簡単に書けるようになるかな?多分こんな感じで良さそう

@inlinable public func debug<each T, U>(_ items: repeat (@autoclosure () -> each T), _ lastItem: @autoclosure () -> U) {
#if DEBUG
    repeat print(each items, terminator=" ")
    print(lastItem)
#endif
}
ensan-hcl commented 1 year ago

FullConversionだとあまり効果がないが、GradualConversionでは8%くらいの改善になってる!

ensan-hcl commented 1 year ago

some Anyにする意味があるのかも合わせてチェックする。こういう感じ。

@inlinable public func debug(_ item1: @autoclosure () -> Any) {
#if DEBUG
    print(item1())
#endif
}

あんまり変わらないか僅かにいいので、some AnyではなくAnyでいく。