UnityC#にて
var list = new List<int>(10)
というように初期に最低限必要と思われるメモリ容量を確保しておくと処理が軽くなって高速化するときいた
UnityC# で手軽にできる高速化テクニックを7種類、紹介しています。※コメントにて動画の補足情報があります。 ▼『Unity使いこなし術』の再生リスト
https://www.youtube.com/playlist?list=PLKDiJl9C6HD43V-HdFI55pUkXsMR3N_Ib ★今回の内容...
そこでSwiftではどのようにこの初期メモリ確保できるのか調べたところ
reserveCapacityという物があった
ではどれくらい速くなるのだろうか気になったので調べた
環境
MacBook Pro (13-inch, 2018)
MacOS Catalina 10.15.6
Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
結論
- reserveCapacityを使っても使わなくてもほぼ変わらない
- 確保したCapacityサイズが小さい場合、遅くなる
- 余裕を持ってCapacityを確保すると少し速くなる時が稀にある
- 特別な理由がなければ使う必要なさそう
僕の測定方法が正しければこの結果になる。
UnityC#ほど重要視する必要ないように思った
まあ、Swift(速い)というだけ最適化されてるのかな?
実験
使用したコードと結果を貼り付けておきます
Benchmarkクラスは他の時も使うので少しオプションが多くなっています。
読みにくくてすみません。
Benchmark.swift
まず、使用したコードです。
なんとなくArrayクラスも測定してみました。
import Foundation
Benchmark.Excute("set capacity", decimal: 5, ave: true){
var a: [Int] = []
a.reserveCapacity(100000)
for i in 0...100000 {
a.append(i)
}
}
Benchmark.Excute("normal", decimal: 5, ave: true){
var a: [Int] = []
for i in 0...100000 {
a.append(i)
}
}
Benchmark.Excute("use Array class", decimal: 5, ave: true){
var a: Array<Int> = Array()
for i in 0...100000 {
a.append(i)
}
}
class Benchmark {
static func Excute( _ name: String, decimal: Int = 3 , ave: Bool = false , _ process: () -> ()) {
let aveLoop: Int = 20
var elapsed: TimeInterval
if ave {
var r: TimeInterval = 0
for _ in 0...aveLoop {
let start = Date()
process()
r += Date().timeIntervalSince(start)
}
elapsed = r/Double(aveLoop)
}else {
let start = Date()
process()
elapsed = Date().timeIntervalSince(start)
}
let formatedElapsed = String(format: "%.\(decimal)f", elapsed)
print("""
[result]
name : \(name)
time : \(formatedElapsed)
""")
}
}
結果
Capacityを確保した時0.09695 ~ 0.09772
普通の配列(Capacityを確保しない)
0.09641 ~ 0.09699
Arrayクラス
0.09541 ~ 0.09777
まとめ
何も気にせずに普通の配列使ってればいいなと思いました。
ミスや、僕が勘違いしている点などがあったら指摘していただけると嬉しいです。
0 件のコメント:
コメントを投稿