Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Swift] Adds new API to reduce memory copying within swift #8484

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
*/

import Benchmark
import CoreFoundation
import FlatBuffers
import Foundation

@usableFromInline
struct AA: NativeStruct {
Expand All @@ -29,6 +29,15 @@ struct AA: NativeStruct {
}

let benchmarks = {
let oneGB: Int32 = 1_024_000_000
let data = {
var array = [8888.88, 8888.88]
var data = Data()
array.withUnsafeBytes { ptr in
data.append(contentsOf: ptr)
}
return data
}()
let ints: [Int] = Array(repeating: 42, count: 100)
let bytes: [UInt8] = Array(repeating: 42, count: 100)
let str10 = (0...9).map { _ -> String in "x" }.joined()
Expand Down Expand Up @@ -73,12 +82,25 @@ let benchmarks = {

Benchmark("Allocating 1GB", configuration: singleConfiguration) { benchmark in
for _ in benchmark.scaledIterations {
blackHole(FlatBufferBuilder(initialSize: 1_024_000_000))
blackHole(FlatBufferBuilder(initialSize: oneGB))
}
}

Benchmark(
"Allocating ByteBuffer 1GB",
configuration: singleConfiguration)
{ benchmark in
let memory = UnsafeMutableRawPointer.allocate(
byteCount: 1_024_000_000,
alignment: 1)
benchmark.startMeasurement()
for _ in benchmark.scaledIterations {
blackHole(ByteBuffer(assumingMemoryBound: memory, capacity: Int(oneGB)))
}
}

Benchmark("Clearing 1GB", configuration: singleConfiguration) { benchmark in
var fb = FlatBufferBuilder(initialSize: 1_024_000_000)
var fb = FlatBufferBuilder(initialSize: oneGB)
benchmark.startMeasurement()
for _ in benchmark.scaledIterations {
blackHole(fb.clear())
Expand Down Expand Up @@ -158,6 +180,26 @@ let benchmarks = {
}
}

Benchmark(
"FlatBufferBuilder Start table",
configuration: kiloConfiguration)
{ benchmark in
var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
benchmark.startMeasurement()
for _ in benchmark.scaledIterations {
let s = fb.startTable(with: 4)
blackHole(fb.endTable(at: s))
}
}

Benchmark("Struct") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
benchmark.startMeasurement()
for _ in benchmark.scaledIterations {
blackHole(fb.create(struct: array.first!))
}
}

Benchmark("Structs") { benchmark in
let rawSize = ((16 * 5) * benchmark.scaledIterations.count) / 1024
var fb = FlatBufferBuilder(initialSize: Int32(rawSize * 1600))
Expand All @@ -176,7 +218,7 @@ let benchmarks = {
let start = fb.startTable(with: 1)
fb.add(offset: vector, at: 4)
let root = Offset(offset: fb.endTable(at: start))
fb.finish(offset: root)
blackHole(fb.finish(offset: root))
}

Benchmark("Vector of Offsets") { benchmark in
Expand All @@ -198,4 +240,11 @@ let benchmarks = {
blackHole(fb.endTable(at: s))
}
}

Benchmark("Reading Doubles") { benchmark in
let byteBuffer = ByteBuffer(data: data)
for _ in benchmark.scaledIterations {
blackHole(byteBuffer.read(def: Double.self, position: 0))
}
}
}
2 changes: 1 addition & 1 deletion docs-old/source/Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -3261,7 +3261,7 @@ mutators like so:
</div>
<div class="language-swift">
~~~{.swift}
let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
monster.mutate(hp: 10) // mutates a value in a table
/// to mutate structs in swift you have to use the mutable accessors
monster.mutablePos.mutate(z: 4) // mutates a value in a struct
Expand Down
2 changes: 1 addition & 1 deletion docs/source/languages/swift.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ a data object from the server, which you can pass into the `GetRootAsMonster` fu
let url = URL(fileURLWithPath: path, isDirectory: true).appendingPathComponent("monsterdata_test").appendingPathExtension("mon")
guard let data = try? Data(contentsOf: url) else { return }

let monster = Monster.getRootAsMonster(bb: ByteBuffer(data: data))
let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Now you can access values like this:
Expand Down
2 changes: 2 additions & 0 deletions docs/source/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -2011,6 +2011,8 @@ like so:
let buf = builder.sizedByteArray
// or you can use to get an object of type Data
let bufData = ByteBuffer(data: builder.data)
// or
let buf = builder.sizedBuffer
```

=== "TypeScript"
Expand Down
3 changes: 1 addition & 2 deletions grpc/examples/swift/Greeter/Sources/Model/greeter.grpc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ public extension GRPCFlatBufPayload {
self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: serializedByteBuffer.readableBytesView, count: serializedByteBuffer.readableBytes))
}
func serialize(into buffer: inout NIO.ByteBuffer) throws {
let buf = UnsafeRawBufferPointer(start: self.rawPointer, count: Int(self.size))
buffer.writeBytes(buf)
withUnsafeReadableBytes { buffer.writeBytes($0) }
}
}
extension Message: GRPCFlatBufPayload {}
Expand Down
5 changes: 1 addition & 4 deletions grpc/src/compiler/swift_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,7 @@ grpc::string GenerateHeader() {
code += " }\n";

code += " func serialize(into buffer: inout NIO.ByteBuffer) throws {\n";
code +=
" let buf = UnsafeRawBufferPointer(start: self.rawPointer, count: "
"Int(self.size))\n";
code += " buffer.writeBytes(buf)\n";
code += " withUnsafeReadableBytes { buffer.writeBytes($0) }\n";
code += " }\n";
code += "}\n";
code += "extension Message: GRPCFlatBufPayload {}\n";
Expand Down
Loading
Loading