From 78659f48c58294454de26b8649b08b62b9bf913c Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Mon, 4 Sep 2023 17:41:19 +0300 Subject: [PATCH] bench: a new bench/ directory for language benchmarks --- bench/README.md | 15 +++ bench/vectors/README.md | 13 +++ bench/vectors/vectors.cs | 191 +++++++++++++++++++++++++++++++++++++++ bench/vectors/vectors.v | 165 +++++++++++++++++++++++++++++++++ 4 files changed, 384 insertions(+) create mode 100644 bench/README.md create mode 100644 bench/vectors/README.md create mode 100644 bench/vectors/vectors.cs create mode 100644 bench/vectors/vectors.v diff --git a/bench/README.md b/bench/README.md new file mode 100644 index 0000000000..7386eb08c9 --- /dev/null +++ b/bench/README.md @@ -0,0 +1,15 @@ +### Vectors + +```bash +Benchmark 1: ./boids_test/bin/Release/net7.0/linux-x64/publish/boids_test +Time (mean ± σ): 262.2 ms ± 5.7 ms [User: 231.6 ms, System: 14.1 ms] +Range (min … max): 255.4 ms … 275.3 ms 11 runs + +Benchmark 2: ./vinted_report_generator/main +Time (mean ± σ): 208.3 ms ± 1.9 ms [User: 205.4 ms, System: 1.6 ms] +Range (min … max): 204.9 ms … 210.6 ms 14 runs + +Summary +./vinted_report_generator/main ran +1.26 ± 0.03 times faster than ./boids_test/bin/Release/net7.0/linux-x64/publish/boids_test +``` diff --git a/bench/vectors/README.md b/bench/vectors/README.md new file mode 100644 index 0000000000..8cb9cd0c73 --- /dev/null +++ b/bench/vectors/README.md @@ -0,0 +1,13 @@ +```bash +Benchmark 1: ./boids_test/bin/Release/net7.0/linux-x64/publish/boids_test +Time (mean ± σ): 262.2 ms ± 5.7 ms [User: 231.6 ms, System: 14.1 ms] +Range (min … max): 255.4 ms … 275.3 ms 11 runs + +Benchmark 2: ./vinted_report_generator/main +Time (mean ± σ): 208.3 ms ± 1.9 ms [User: 205.4 ms, System: 1.6 ms] +Range (min … max): 204.9 ms … 210.6 ms 14 runs + +Summary +./vinted_report_generator/main ran +1.26 ± 0.03 times faster than ./boids_test/bin/Release/net7.0/linux-x64/publish/boids_test +``` diff --git a/bench/vectors/vectors.cs b/bench/vectors/vectors.cs new file mode 100644 index 0000000000..691997497d --- /dev/null +++ b/bench/vectors/vectors.cs @@ -0,0 +1,191 @@ +internal readonly struct Vector +{ + public readonly double X; + public readonly double Y; + public readonly double Z; + + public Vector(double x, double y, double z) + { + X = x; + Y = y; + Z = z; + } + + public override string ToString() + { + return $"({X}, {Y}, {Z})"; + } +} + +internal static class Program +{ + public static void Main() + { + const int boidsCount = 10000; + + var positions = new Vector[boidsCount]; + var velocities = new Vector[boidsCount]; + + const double maxCoordinate = 10000.0; + + var random = new Random(); + + for (var positionIndex = 0; positionIndex < positions.Length; positionIndex++) + { + positions[positionIndex] = new Vector( + x: random.NextDouble() * maxCoordinate, + y: random.NextDouble() * maxCoordinate, + z: random.NextDouble() * maxCoordinate + ); + } + + const double cohesionDistance = 10.0; + const double separationDistance = 5.0; + + var closeBoids = new List(); + + for (var boidIndex = 0; boidIndex < positions.Length; boidIndex++) + { + var position = positions[boidIndex]; + closeBoids.Clear(); + + for (var otherBoidIndex = 0; otherBoidIndex < positions.Length; otherBoidIndex++) + { + if (boidIndex == otherBoidIndex) + { + continue; + } + + var otherPosition = positions[otherBoidIndex]; + + var differenceX = position.X - otherPosition.X; + var differenceY = position.Y - otherPosition.Y; + var differenceZ = position.Z - otherPosition.Z; + + var distance = Math.Sqrt( + differenceX * differenceX + + differenceY * differenceY + + differenceZ * differenceZ + ); + + if (distance <= cohesionDistance) + { + closeBoids.Add(otherBoidIndex); + } + } + + if (closeBoids.Count == 0) + { + continue; + } + + var cohesion = new Vector(0.0, 0.0, 0.0); + var separation = new Vector(0.0, 0.0, 0.0); + var separationCount = 0; + var alignment = new Vector(0.0, 0.0, 0.0); + + foreach (var closeBoidIndex in closeBoids) + { + var closeBoidPosition = positions[closeBoidIndex]; + + cohesion = new Vector( + cohesion.X + closeBoidPosition.X, + cohesion.Y + closeBoidPosition.Y, + cohesion.Z + closeBoidPosition.Z + ); + + var differenceFromClosest = new Vector( + position.X - closeBoidPosition.X, + position.Y - closeBoidPosition.Y, + position.Z - closeBoidPosition.Z + ); + + var differenceMagnitude = Math.Sqrt(differenceFromClosest.X * differenceFromClosest.X + differenceFromClosest.Y * differenceFromClosest.Y + differenceFromClosest.Z * differenceFromClosest.Z); + + if (differenceMagnitude <= separationDistance) + { + separation = new Vector( + separation.X + differenceFromClosest.X / differenceMagnitude, + separation.Y + differenceFromClosest.Y / differenceMagnitude, + separation.Z + differenceFromClosest.Z / differenceMagnitude + ); + + separationCount++; + } + + var closeBoidVelocity = velocities[closeBoidIndex]; + + alignment = new Vector( + alignment.X + closeBoidVelocity.X, + alignment.Y + closeBoidVelocity.Y, + alignment.Z + closeBoidVelocity.Z + ); + } + + cohesion = new Vector( + cohesion.X / closeBoids.Count, + cohesion.Y / closeBoids.Count, + cohesion.Z / closeBoids.Count + ); + + var cohesionForce = new Vector( + cohesion.X - position.X, + cohesion.Y - position.Y, + cohesion.Z - position.Z + ); + + if (separationCount > 0) + { + separation = new Vector( + separation.X / separationCount, + separation.Y / separationCount, + separation.Z / separationCount + ); + } + + alignment = new Vector( + alignment.X / closeBoids.Count, + alignment.Y / closeBoids.Count, + alignment.Z / closeBoids.Count + ); + + var currentVelocity = velocities[boidIndex]; + + velocities[boidIndex] = new Vector( + currentVelocity.X + cohesionForce.X + separation.X + alignment.X, + currentVelocity.Y + cohesionForce.Y + separation.Y + alignment.Y, + currentVelocity.Z + cohesionForce.Z + separation.Z + alignment.Z + ); + } + + var positionSum = new Vector(0.0, 0.0, 0.0); + var velocitySum = new Vector(0.0, 0.0, 0.0); + + for (var boidIndex = 0; boidIndex < positions.Length; boidIndex++) + { + var position = positions[boidIndex]; + var velocity = velocities[boidIndex]; + + positions[boidIndex] = new Vector( + position.X + velocity.X, + position.Y + velocity.Y, + position.Z + velocity.Z + ); + + positionSum = new Vector( + positionSum.X + position.X, + positionSum.Y + position.Y, + positionSum.Z + position.Z + ); + + velocitySum = new Vector( + velocitySum.X + velocity.X, + velocitySum.Y + velocity.Y, + velocitySum.Z + velocity.Z + ); + } + + Console.WriteLine(positionSum.ToString()); + Console.WriteLine(velocitySum.ToString()); + } +} \ No newline at end of file diff --git a/bench/vectors/vectors.v b/bench/vectors/vectors.v new file mode 100644 index 0000000000..0504ff0506 --- /dev/null +++ b/bench/vectors/vectors.v @@ -0,0 +1,165 @@ +module main + +import rand +import math + +struct Vector { + x f64 + y f64 + z f64 +} + +const ( + boids_count = 10000 + max_coordinate = 10000.0 + cohesion_distance = 10.0 + separation_distance = 5.0 +) + +[direct_array_access] +fn main() { + mut positions := [boids_count]Vector{} + mut velocities := [boids_count]Vector{} + + for position_index in 0 .. positions.len { + positions[position_index] = Vector{ + x: rand.f64() * max_coordinate + y: rand.f64() * max_coordinate + z: rand.f64() * max_coordinate + } + } + + for boid_index in 0 .. positions.len { + position := positions[boid_index] + mut close_boids_ids := []int{} + + for other_boid_index in 0 .. positions.len { + if boid_index == other_boid_index { + continue + } + + other_position := positions[other_boid_index] + + difference_x := position.x - other_position.x + difference_y := position.y - other_position.y + difference_z := position.z - other_position.z + + distance := math.sqrt(difference_x * difference_x + + difference_y * difference_y + + difference_z * difference_z) + + if distance <= cohesion_distance { + close_boids_ids << other_boid_index + } + } + + if close_boids_ids.len == 0 { + continue + } + + mut cohesion := Vector{} + mut separation := Vector{} + mut separation_count := 0 + mut alignment := Vector{} + + for close_boid_id in close_boids_ids { + close_boid_position := positions[close_boid_id] + + cohesion = Vector{ + x: cohesion.x + close_boid_position.x + y: cohesion.y + close_boid_position.y + z: cohesion.z + close_boid_position.z + } + + difference_from_closest := Vector{ + x: position.x - close_boid_position.x + y: position.y - close_boid_position.y + z: position.z - close_boid_position.z + } + + difference_magnitude := math.sqrt(difference_from_closest.x * difference_from_closest.x + + difference_from_closest.y * difference_from_closest.y + difference_from_closest.z * difference_from_closest.z) + + if difference_magnitude <= separation_distance { + separation = Vector{ + x: separation.x + difference_from_closest.x / difference_magnitude + y: separation.y + difference_from_closest.y / difference_magnitude + z: separation.z + difference_from_closest.z / difference_magnitude + } + + separation_count += 1 + } + + close_boid_velocity := velocities[close_boid_id] + + alignment = Vector{ + x: alignment.x + close_boid_velocity.x + y: alignment.y + close_boid_velocity.y + z: alignment.z + close_boid_velocity.z + } + } + + cohesion = Vector{ + x: cohesion.x / close_boids_ids.len + y: cohesion.y / close_boids_ids.len + z: cohesion.z / close_boids_ids.len + } + + cohesion_force := Vector{ + x: cohesion.x - position.x + y: cohesion.y - position.y + z: cohesion.z - position.z + } + + if separation_count > 0 { + separation = Vector{ + x: separation.x / separation_count + y: separation.y / separation_count + z: separation.z / separation_count + } + } + + alignment = Vector{ + x: alignment.x / close_boids_ids.len + y: alignment.y / close_boids_ids.len + z: alignment.z / close_boids_ids.len + } + + current_velocity := velocities[boid_index] + + velocities[boid_index] = Vector{ + x: current_velocity.x + cohesion_force.x + separation.x + alignment.x + y: current_velocity.y + cohesion_force.y + separation.y + alignment.y + z: current_velocity.z + cohesion_force.z + separation.z + alignment.z + } + } + + mut position_sum := Vector{} + mut velocity_sum := Vector{} + + for boid_index in 0 .. positions.len { + position := positions[boid_index] + velocity := velocities[boid_index] + + positions[boid_index] = Vector{ + x: position.x + velocity.x + y: position.y + velocity.y + z: position.z + velocity.z + } + + position_sum = Vector{ + x: position_sum.x + position.x + y: position_sum.y + position.y + z: position_sum.z + position.z + } + + velocity_sum = Vector{ + x: velocity_sum.x + velocity.x + y: velocity_sum.y + velocity.y + z: velocity_sum.z + velocity.z + } + } + + println('${position_sum.x} - ${position_sum.y} - ${position_sum.z}') + println('${velocity_sum.x} - ${velocity_sum.y} - ${velocity_sum.z}') +}