adding package-benchmark sub-project (#64)
This commit is contained in:
parent
0b3ba9241b
commit
e0ee97bd7f
|
|
@ -1,5 +1,6 @@
|
|||
ignore:
|
||||
- "Tests/"
|
||||
- "Benchmarks/"
|
||||
|
||||
comment:
|
||||
layout: header, changes, diff
|
||||
layout: header, changes, diff
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// Base.swift
|
||||
// FirebladeECSTests
|
||||
//
|
||||
// Created by Christian Treffs on 09.10.17.
|
||||
//
|
||||
|
||||
import FirebladeECS
|
||||
|
||||
class EmptyComponent: Component {}
|
||||
|
||||
class Name: Component {
|
||||
var name: String
|
||||
init(name: String) {
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
class Position: Component {
|
||||
var x: Int
|
||||
var y: Int
|
||||
init(x: Int, y: Int) {
|
||||
self.x = x
|
||||
self.y = y
|
||||
}
|
||||
}
|
||||
|
||||
class Velocity: Component {
|
||||
var a: Float
|
||||
init(a: Float) {
|
||||
self.a = a
|
||||
}
|
||||
}
|
||||
|
||||
class Party: Component {
|
||||
var partying: Bool
|
||||
init(partying: Bool) {
|
||||
self.partying = partying
|
||||
}
|
||||
}
|
||||
|
||||
class Color: Component {
|
||||
var r: UInt8 = 0
|
||||
var g: UInt8 = 0
|
||||
var b: UInt8 = 0
|
||||
}
|
||||
|
||||
class ExampleSystem {
|
||||
private let family: Family2<Position, Velocity>
|
||||
|
||||
init(nexus: Nexus) {
|
||||
family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: EmptyComponent.self)
|
||||
}
|
||||
|
||||
func update(deltaT _: Double) {
|
||||
for (position, velocity) in family {
|
||||
position.x *= 2
|
||||
velocity.a *= 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class SingleGameState: SingleComponent {
|
||||
var shouldQuit: Bool = false
|
||||
var playerHealth: Int = 67
|
||||
}
|
||||
|
||||
func setUpNexus() -> Nexus {
|
||||
let numEntities = 10000
|
||||
let nexus = Nexus()
|
||||
|
||||
for i in 0 ..< numEntities {
|
||||
nexus.createEntity().assign(Position(x: 1 + i, y: 2 + i),
|
||||
Name(name: "myName\(i)"),
|
||||
Velocity(a: 3.14),
|
||||
EmptyComponent(),
|
||||
Color())
|
||||
}
|
||||
|
||||
precondition(nexus.numEntities == numEntities)
|
||||
// precondition(nexus.numFamilies == 1)
|
||||
precondition(nexus.numComponents == numEntities * 5)
|
||||
|
||||
return nexus
|
||||
}
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
// swiftformat:disable preferForLoop
|
||||
import Benchmark
|
||||
import FirebladeECS
|
||||
|
||||
// derived from FirebladeECSPerformanceTests/TypedFamilyPerformanceTests.swift in the parent project
|
||||
|
||||
let benchmarks = {
|
||||
Benchmark("TraitMatching") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let a = nexus.createEntity()
|
||||
a.assign(Position(x: 1, y: 2))
|
||||
a.assign(Name(name: "myName"))
|
||||
a.assign(Velocity(a: 3.14))
|
||||
a.assign(EmptyComponent())
|
||||
|
||||
let isMatch = nexus.family(requiresAll: Position.self, Velocity.self,
|
||||
excludesAll: Party.self)
|
||||
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
isMatch.canBecomeMember(a)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark("TypedFamilyEntities") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requires: Position.self, excludesAll: Party.self)
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.entities
|
||||
.forEach { (entity: Entity) in
|
||||
_ = entity
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark("TypedFamilyOneComponent") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requires: Position.self, excludesAll: Party.self)
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.forEach { (position: Position) in
|
||||
_ = position
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark("TypedFamilyEntityOneComponent") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requires: Position.self, excludesAll: Party.self)
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.entityAndComponents
|
||||
.forEach { (entity: Entity, position: Position) in
|
||||
_ = entity
|
||||
_ = position
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark("TypedFamilyTwoComponents") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: Party.self)
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.forEach { (position: Position, velocity: Velocity) in
|
||||
_ = position
|
||||
_ = velocity
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Benchmark("TypedFamilyEntityTwoComponents") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: Party.self)
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.entityAndComponents
|
||||
.forEach { (entity: Entity, position: Position, velocity: Velocity) in
|
||||
_ = entity
|
||||
_ = position
|
||||
_ = velocity
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark("TypedFamilyThreeComponents") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, excludesAll: Party.self)
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.forEach { (position: Position, velocity: Velocity, name: Name) in
|
||||
_ = position
|
||||
_ = velocity
|
||||
_ = name
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Benchmark("TypedFamilyEntityThreeComponents") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, excludesAll: Party.self)
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.entityAndComponents
|
||||
.forEach { (entity: Entity, position: Position, velocity: Velocity, name: Name) in
|
||||
_ = entity
|
||||
_ = position
|
||||
_ = velocity
|
||||
_ = name
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark("TypedFamilyFourComponents") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, excludesAll: Party.self)
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.forEach { (position: Position, velocity: Velocity, name: Name, color: Color) in
|
||||
_ = position
|
||||
_ = velocity
|
||||
_ = name
|
||||
_ = color
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark("TypedFamilyEntityFourComponents") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, excludesAll: Party.self)
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.entityAndComponents
|
||||
.forEach { (entity: Entity, position: Position, velocity: Velocity, name: Name, color: Color) in
|
||||
_ = entity
|
||||
_ = position
|
||||
_ = velocity
|
||||
_ = name
|
||||
_ = color
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark("TypedFamilyFiveComponents") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, EmptyComponent.self, excludesAll: Party.self)
|
||||
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(
|
||||
family
|
||||
.forEach { (position: Position, velocity: Velocity, name: Name, color: Color, empty: EmptyComponent) in
|
||||
_ = position
|
||||
_ = velocity
|
||||
_ = name
|
||||
_ = color
|
||||
_ = empty
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Benchmark("TypedFamilyEntityFiveComponents") { benchmark in
|
||||
let nexus = setUpNexus()
|
||||
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, EmptyComponent.self, excludesAll: Party.self)
|
||||
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(family
|
||||
.entityAndComponents
|
||||
.forEach { (entity: Entity, position: Position, velocity: Velocity, name: Name, color: Color, empty: EmptyComponent) in
|
||||
_ = entity
|
||||
_ = position
|
||||
_ = velocity
|
||||
_ = name
|
||||
_ = color
|
||||
_ = empty
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// swift-tools-version: 5.8
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "ECSBenchmarks",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.macOS(.v13)
|
||||
],
|
||||
dependencies: [
|
||||
.package(path: "../"),
|
||||
.package(url: "https://github.com/ordo-one/package-benchmark", .upToNextMajor(from: "1.4.0"))
|
||||
],
|
||||
targets: [
|
||||
.executableTarget(
|
||||
name: "ECSBenchmark",
|
||||
dependencies: [
|
||||
.product(name: "FirebladeECS", package: "ecs"),
|
||||
.product(name: "Benchmark", package: "package-benchmark")
|
||||
],
|
||||
path: "Benchmarks/ECSBenchmark",
|
||||
plugins: [
|
||||
.plugin(name: "BenchmarkPlugin", package: "package-benchmark")
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Benchmarks for FirebladeECS
|
||||
|
||||
Originally seeded by replicating performance tests into a new form leveraging [package-benchmark](https://swiftpackageindex.com/ordo-one/package-benchmark/) [Documentation](https://swiftpackageindex.com/ordo-one/package-benchmark/main/documentation/benchmark).
|
||||
|
||||
To run all the available benchmarks:
|
||||
|
||||
swift package benchmark --format markdown
|
||||
|
||||
For more help on the package-benchmark SwiftPM plugin:
|
||||
|
||||
swift package benchmark help
|
||||
|
||||
Creating a local baseline:
|
||||
|
||||
swift package --allow-writing-to-package-directory benchmark baseline update dev
|
||||
swift package benchmark baseline list
|
||||
|
||||
Comparing to a the baseline 'alpha'
|
||||
|
||||
swift package benchmark baseline compare dev
|
||||
|
||||
For more details on creating and comparing baselines, read [Creating and Comparing Benchmark Baselines](https://swiftpackageindex.com/ordo-one/package-benchmark/main/documentation/benchmark/creatingandcomparingbaselines).
|
||||
Loading…
Reference in New Issue