Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9609ff5

Browse files
committed
Adds Nativestructs pointer push into ByteBuffer
Updates benchmarks & cleanup Adds native struct vector tests
1 parent b08abbb commit 9609ff5

File tree

9 files changed

+221
-118
lines changed

9 files changed

+221
-118
lines changed

swift/Sources/FlatBuffers/ByteBuffer.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,20 @@ public struct ByteBuffer {
238238
}
239239
}
240240

241+
/// Adds an array of type Scalar to the buffer memory
242+
/// - Parameter elements: An array of Scalars
243+
@inline(__always)
244+
@usableFromInline
245+
mutating func push<T: NativeStruct>(elements: [T]) {
246+
elements.withUnsafeBytes { ptr in
247+
ensureSpace(size: ptr.count)
248+
_storage.memory
249+
.advanced(by: writerIndex &- ptr.count)
250+
.copyMemory(from: ptr.baseAddress!, byteCount: ptr.count)
251+
self._writerSize = self._writerSize &+ ptr.count
252+
}
253+
}
254+
241255
/// Adds a `ContiguousBytes` to buffer memory
242256
/// - Parameter value: bytes to copy
243257
#if swift(>=5.0) && !os(WASI)
@@ -248,8 +262,8 @@ public struct ByteBuffer {
248262
ensureSpace(size: ptr.count)
249263
memcpy(
250264
_storage.memory.advanced(by: writerIndex &- ptr.count),
251-
UnsafeRawPointer(ptr.baseAddress!),
252-
ptr.count)
265+
UnsafeRawPointer(ptr.baseAddress!),
266+
ptr.count)
253267
self._writerSize = self._writerSize &+ ptr.count
254268
}
255269
}

swift/Sources/FlatBuffers/FlatBufferBuilder.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,9 +623,7 @@ public struct FlatBufferBuilder {
623623
startVector(
624624
structs.count * MemoryLayout<T>.size,
625625
elementSize: MemoryLayout<T>.alignment)
626-
for i in structs.reversed() {
627-
_ = create(struct: i)
628-
}
626+
_bb.push(elements: structs)
629627
return endVector(len: structs.count)
630628
}
631629

swift/Sources/FlatBuffers/Verifiable.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ public enum Vector<U, S>: Verifiable where U: Verifiable, S: Verifiable {
129129
let range = try verifyRange(&verifier, at: position, of: UOffset.self)
130130
for index in stride(
131131
from: range.start,
132-
to: Int(clamping: range.start &+ (range.count &* MemoryLayout<Int32>.size)),
132+
to: Int(
133+
clamping: range
134+
.start &+ (range.count &* MemoryLayout<Int32>.size)),
133135
by: MemoryLayout<UOffset>.size)
134136
{
135137
try U.verify(&verifier, at: index, of: U.self)
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
///*
2+
// * Copyright 2023 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 Benchmark
18+
import CoreFoundation
19+
import FlatBuffers
20+
21+
@usableFromInline
22+
struct AA: NativeStruct {
23+
public init(a: Double, b: Double) {
24+
self.a = a
25+
self.b = b
26+
}
27+
var a: Double
28+
var b: Double
29+
}
30+
31+
let benchmarks = {
32+
let ints: [Int] = Array(repeating: 42, count: 100)
33+
let bytes: [UInt8] = Array(repeating: 42, count: 100)
34+
let str = (0...99).map { _ -> String in "x" }.joined()
35+
let array: [AA] = [
36+
AA(a: 2.4, b: 2.4),
37+
AA(a: 2.4, b: 2.4),
38+
AA(a: 2.4, b: 2.4),
39+
AA(a: 2.4, b: 2.4),
40+
AA(a: 2.4, b: 2.4),
41+
]
42+
43+
Benchmark("Allocating") { benchmark in
44+
for i in benchmark.scaledIterations {
45+
var fb = FlatBufferBuilder(initialSize: 1_024_000_000)
46+
}
47+
}
48+
49+
Benchmark("Strings 10") { benchmark in
50+
var fb = FlatBufferBuilder(initialSize: 1<<20)
51+
for i in benchmark.scaledIterations {
52+
benchmark.startMeasurement()
53+
for _ in 0..<1_000_000 {
54+
_ = fb.create(string: "foobarbaz")
55+
}
56+
benchmark.stopMeasurement()
57+
fb.clear()
58+
}
59+
}
60+
61+
Benchmark("Strings 100") { benchmark in
62+
var fb = FlatBufferBuilder(initialSize: 1<<20)
63+
for i in benchmark.scaledIterations {
64+
benchmark.startMeasurement()
65+
for _ in 0..<1_000_000 {
66+
_ = fb.create(string: str)
67+
}
68+
benchmark.stopMeasurement()
69+
fb.clear()
70+
}
71+
}
72+
73+
Benchmark("Vector 100 Ints") { benchmark in
74+
var fb = FlatBufferBuilder(initialSize: 1<<20)
75+
benchmark.startMeasurement()
76+
for i in benchmark.scaledIterations {
77+
benchmark.startMeasurement()
78+
for _ in 0..<1_000_000 {
79+
_ = fb.createVector(ints)
80+
}
81+
benchmark.stopMeasurement()
82+
fb.clear()
83+
}
84+
}
85+
86+
Benchmark("Vector 100 Bytes") { benchmark in
87+
var fb = FlatBufferBuilder(initialSize: 1<<20)
88+
for i in benchmark.scaledIterations {
89+
benchmark.startMeasurement()
90+
for _ in 0..<1_000_000 {
91+
_ = fb.createVector(bytes)
92+
}
93+
benchmark.stopMeasurement()
94+
fb.clear()
95+
}
96+
}
97+
98+
Benchmark("Vector 100 ContiguousBytes") { benchmark in
99+
var fb = FlatBufferBuilder(initialSize: 1<<20)
100+
for i in benchmark.scaledIterations {
101+
benchmark.startMeasurement()
102+
for _ in 0..<1_000_000 {
103+
_ = fb.createVector(bytes: bytes)
104+
}
105+
benchmark.stopMeasurement()
106+
fb.clear()
107+
}
108+
}
109+
110+
Benchmark("FlatBufferBuilder Add") { benchmark in
111+
var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
112+
for _ in benchmark.scaledIterations {
113+
benchmark.startMeasurement()
114+
for _ in 0..<1_000_000 {
115+
let off = fb.create(string: "T")
116+
let s = fb.startTable(with: 4)
117+
fb.add(element: 3.2, def: 0, at: 2)
118+
fb.add(element: 4.2, def: 0, at: 4)
119+
fb.add(element: 5.2, def: 0, at: 6)
120+
fb.add(offset: off, at: 8)
121+
_ = fb.endTable(at: s)
122+
}
123+
benchmark.stopMeasurement()
124+
fb.clear()
125+
}
126+
}
127+
128+
Benchmark("structs") { benchmark in
129+
let structCount = 1_000_000
130+
131+
let rawSize = ((16 * 5) * structCount) / 1024
132+
133+
var fb = FlatBufferBuilder(initialSize: Int32(rawSize * 1600))
134+
135+
for _ in benchmark.scaledIterations {
136+
benchmark.startMeasurement()
137+
var offsets: [Offset] = []
138+
for _ in 0..<structCount {
139+
let vector = fb.createVector(
140+
ofStructs: array)
141+
let start = fb.startTable(with: 1)
142+
fb.add(offset: vector, at: 4)
143+
offsets.append(Offset(offset: fb.endTable(at: start)))
144+
}
145+
let vector = fb.createVector(ofOffsets: offsets)
146+
let start = fb.startTable(with: 1)
147+
fb.add(offset: vector, at: 4)
148+
let root = Offset(offset: fb.endTable(at: start))
149+
fb.finish(offset: root)
150+
benchmark.stopMeasurement()
151+
fb.clear()
152+
}
153+
}
154+
}

tests/swift/benchmarks/Package.swift

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.1
1+
// swift-tools-version:5.8
22
/*
33
* Copyright 2020 Google Inc. All rights reserved.
44
*
@@ -20,15 +20,23 @@ import PackageDescription
2020
let package = Package(
2121
name: "benchmarks",
2222
platforms: [
23-
.macOS(.v10_14),
23+
.macOS(.v13),
2424
],
2525
dependencies: [
2626
.package(path: "../../.."),
27-
.package(url: "https://github.com/google/swift-benchmark", from: "0.1.0"),
27+
.package(
28+
url: "https://github.com/ordo-one/package-benchmark",
29+
from: "1.12.0"),
2830
],
2931
targets: [
30-
.target(
31-
name: "benchmarks",
32-
dependencies: ["FlatBuffers",
33-
.product(name: "Benchmark", package: "swift-benchmark")]),
32+
.executableTarget(
33+
name: "FlatbuffersBenchmarks",
34+
dependencies: [
35+
.product(name: "FlatBuffers", package: "flatbuffers"),
36+
.product(name: "Benchmark", package: "package-benchmark"),
37+
],
38+
path: "Benchmarks/FlatbuffersBenchmarks",
39+
plugins: [
40+
.plugin(name: "BenchmarkPlugin", package: "package-benchmark"),
41+
]),
3442
])

tests/swift/benchmarks/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Benchmarks
2+
3+
To open the benchmarks in xcode use:
4+
5+
`open --env BENCHMARK_DISABLE_JEMALLOC=true Package.swift`
6+
7+
or running them directly within terminal using:
8+
9+
`swift package benchmark`

tests/swift/benchmarks/Sources/benchmarks/main.swift

Lines changed: 0 additions & 102 deletions
This file was deleted.

tests/swift/tests/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersNanInfTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ final class FlatBuffersNanInfTests: XCTestCase {
6767
let data = try encoder.encode(reader)
6868
let decoder = JSONDecoder()
6969
decoder.nonConformingFloatDecodingStrategy = .convertFromString(
70-
positiveInfinity: "inf",
71-
negativeInfinity: "-inf",
72-
nan: "nan")
70+
positiveInfinity: "inf",
71+
negativeInfinity: "-inf",
72+
nan: "nan")
7373
decoder.keyDecodingStrategy = .convertFromSnakeCase
7474
let value = try decoder.decode(Test.self, from: data)
7575
XCTAssertEqual(value.value, 100)

tests/swift/tests/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersVectorsTests.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,26 @@ final class FlatBuffersVectors: XCTestCase {
5353
// swiftformat:enable all
5454
}
5555

56+
func testCreateStructArray() {
57+
struct Vec: NativeStruct {
58+
let x, y, z: Float32
59+
}
60+
let vector: [Vec] = [
61+
Vec(x: 1, y: 2, z: 3),
62+
Vec(x: 4, y: 5, z: 6),
63+
Vec(x: 7, y: 8, z: 9),
64+
]
65+
var b = FlatBufferBuilder(initialSize: 100)
66+
let o = b.createVector(ofStructs: vector)
67+
b.finish(offset: o)
68+
vector.withUnsafeBytes { pointer in
69+
print(Array(pointer))
70+
}
71+
// swiftformat:disable all
72+
XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 128, 64, 0, 0, 160, 64, 0, 0, 192, 64, 0, 0, 224, 64, 0, 0, 0, 65, 0, 0, 16, 65])
73+
// swiftformat:enable all
74+
}
75+
5676
func testCreateEmptyIntArray() {
5777
let numbers: [Int32] = []
5878
var b = FlatBufferBuilder(initialSize: 20)

0 commit comments

Comments
 (0)