• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google Inc. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import CoreFoundation
18 import FlatBuffers
19 
20 struct Benchmark {
21   var name: String
22   var value: Double
23 
24   var description: String { "\(String(format: "|\t%@\t\t|\t\t%fs\t|", name, value))"}
25 }
26 
27 func run(name: String, runs: Int, action: () -> Void) -> Benchmark {
28   action()
29   let start = CFAbsoluteTimeGetCurrent()
30   for _ in 0..<runs {
31     action()
32   }
33   let ends = CFAbsoluteTimeGetCurrent()
34   let value = Double(ends - start) / Double(runs)
35   print("done \(name): in \(value)")
36   return Benchmark(name: name, value: value)
37 }
38 
39 
createDocumentnull40 func createDocument(Benchmarks: [Benchmark]) -> String {
41   let separator = "-------------------------------------"
42   var document = "\(separator)\n"
43   document += "\(String(format: "|\t%@\t\t|\t\t%@\t\t|", "Name", "Scores"))\n"
44   document += "\(separator)\n"
45   for i in Benchmarks {
46     document += "\(i.description) \n"
47     document += "\(separator)\n"
48   }
49   return document
50 }
51 
52 @inlinable
create10Stringsnull53 func create10Strings() {
54   var fb = FlatBufferBuilder(initialSize: 1<<20)
55   for _ in 0..<10_000 {
56     _ = fb.create(string: "foobarbaz")
57   }
58 }
59 
60 @inlinable
create100Stringsnull61 func create100Strings(str: String) {
62   var fb = FlatBufferBuilder(initialSize: 1<<20)
63   for _ in 0..<10_000 {
64     _ = fb.create(string: str)
65   }
66 }
67 
68 @inlinable
benchmarkFiveHundredAddsnull69 func benchmarkFiveHundredAdds() {
70   var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
71   for _ in 0..<500_000 {
72     let off = fb.create(string: "T")
73     let s = fb.startTable(with: 4)
74     fb.add(element: 3.2, def: 0, at: 2)
75     fb.add(element: 4.2, def: 0, at: 4)
76     fb.add(element: 5.2, def: 0, at: 6)
77     fb.add(offset: off, at: 8)
78     _ = fb.endTable(at: s)
79   }
80 }
81 
82 @inlinable
benchmarkThreeMillionStructsnull83 func benchmarkThreeMillionStructs() {
84   let structCount = 3_000_000
85 
86   let rawSize = ((16 * 5) * structCount) / 1024
87 
88   var fb = FlatBufferBuilder(initialSize: Int32(rawSize * 1600))
89 
90   var offsets: [Offset] = []
91   for _ in 0..<structCount {
92     fb.startVector(5 * MemoryLayout<AA>.size, elementSize: MemoryLayout<AA>.alignment)
93     for _ in 0..<5 {
94       _ = fb.create(struct: AA(a: 2.4, b: 2.4))
95     }
96     let vector = fb.endVector(len: 5)
97     let start = fb.startTable(with: 1)
98     fb.add(offset: vector, at: 4)
99     offsets.append(Offset(offset: fb.endTable(at: start)))
100   }
101   let vector = fb.createVector(ofOffsets: offsets)
102   let start = fb.startTable(with: 1)
103   fb.add(offset: vector, at: 4)
104   let root = Offset(offset: fb.endTable(at: start))
105   fb.finish(offset: root)
106 }
107 
108 @usableFromInline
109 struct AA: NativeStruct {
110   public init(a: Double, b: Double) {
111     self.a = a
112     self.b = b
113   }
114   var a: Double
115   var b: Double
116 
117 }
118 
benchmarknull119 func benchmark(numberOfRuns runs: Int) {
120   var benchmarks: [Benchmark] = []
121   let str = (0...99).map { _ -> String in "x" }.joined()
122   benchmarks.append(run(name: "500_000", runs: runs, action: benchmarkFiveHundredAdds))
123   benchmarks.append(run(name: "10 str", runs: runs, action: create10Strings))
124   let hundredStr = run(name: "100 str", runs: runs) {
125     create100Strings(str: str)
126   }
127   benchmarks.append(run(name: "3M strc", runs: 1, action: benchmarkThreeMillionStructs))
128   benchmarks.append(hundredStr)
129   print(createDocument(Benchmarks: benchmarks))
130 }
131 
132 benchmark(numberOfRuns: 20)
133