Преглед изворни кода

Refactors `[UInt8].toUInt32Array()` and `[UInt8].toUInt64Array()` to use `Array.init(unsafeUninitializedCapacity:, initializingWith:)`

16% performance gain for `toUInt32Array()` and 7% for`toUInt64Array()`
Valeriy Van пре 5 година
родитељ
комит
8d216531ae
1 измењених фајлова са 25 додато и 12 уклоњено
  1. 25 12
      Sources/CryptoSwift/Collection+Extension.swift

+ 25 - 12
Sources/CryptoSwift/Collection+Extension.swift

@@ -19,13 +19,17 @@ extension Collection where Self.Element == UInt8, Self.Index == Int {
       return []
     }
 
-    var result = Array<UInt32>(reserveCapacity: 16)
-    for idx in stride(from: startIndex, to: endIndex, by: 4) {
-      let val = UInt32(bytes: self, fromIndex: idx).bigEndian
-      result.append(val)
+    let c = strideCount(from: startIndex, to: endIndex, by: 4)
+    return Array<UInt32>(unsafeUninitializedCapacity: c) { buf, count in
+      var counter = 0
+      for idx in stride(from: startIndex, to: endIndex, by: 4) {
+        let val = UInt32(bytes: self, fromIndex: idx).bigEndian
+        buf[counter] = val
+        counter += 1
+      }
+      count = counter
+      assert(counter == c)
     }
-
-    return result
   }
 
   // Big endian order
@@ -34,12 +38,21 @@ extension Collection where Self.Element == UInt8, Self.Index == Int {
       return []
     }
 
-    var result = Array<UInt64>(reserveCapacity: 32)
-    for idx in stride(from: startIndex, to: endIndex, by: 8) {
-      let val = UInt64(bytes: self, fromIndex: idx).bigEndian
-      result.append(val)
+    let c = strideCount(from: startIndex, to: endIndex, by: 8)
+    return Array<UInt64>(unsafeUninitializedCapacity: c) { buf, count in
+      var counter = 0
+      for idx in stride(from: startIndex, to: endIndex, by: 8) {
+        let val = UInt64(bytes: self, fromIndex: idx).bigEndian
+        buf[counter] = val
+        counter += 1
+      }
+      count = counter
+      assert(counter == c)
     }
-
-    return result
   }
 }
+
+private func strideCount(from: Int, to: Int, by: Int) -> Int {
+    let count = to - from
+    return count / by + (count % by > 0 ? 1 : 0)
+}