Skip to content

Instantly share code, notes, and snippets.

@XANOZOID
Created January 21, 2024 01:45
Show Gist options
  • Save XANOZOID/536e37e487977abc2b75bff2dec2f4f3 to your computer and use it in GitHub Desktop.
Save XANOZOID/536e37e487977abc2b75bff2dec2f4f3 to your computer and use it in GitHub Desktop.
Super realistic and useful comparison between go and c++ performance
# Go:
iterations: 283694453
collisions: 1508042
passes: 283698
iterations: 281346118
collisions: 1360134
passes: 281349
iterations: 282386123
collisions: 1224686
passes: 282389
iterations: 290935024
collisions: 2024373
passes: 290939
iterations: 275122369
collisions: 1237025
passes: 275125
# C++:
iterations: 359682175
collisions: 956747
passes: 359686
iterations: 357632503
collisions: 948905
passes: 357637
iterations: 358406536
collisions: 895555
passes: 358409
iterations: 354060271
collisions: 706633
passes: 354063
iterations: 353943962
collisions: 1001485
passes: 353947
#include <iostream>
#include <random>
#include <mutex>
#include <windows.h>
const int THREAD_COUNT = 6;
const int THREAD_LOAD = 1000;
std::atomic<bool> testing = true;
int totalCollisions = 0;
int totalIterations = 0;
int totalPasses = 0;
std::mutex m;
struct fPoint {
public:
float x;
float y;
};
inline float sign(const fPoint p1, const fPoint p2, const fPoint p3)
{
return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
}
bool inline PointInTriangle(const fPoint pt, const fPoint v1, const fPoint v2, const fPoint v3)
{
float d1, d2, d3;
bool has_neg, has_pos;
d1 = sign(pt, v1, v2);
d2 = sign(pt, v2, v3);
d3 = sign(pt, v3, v1);
has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);
return !(has_neg && has_pos);
}
void test3_threaded(const fPoint* points) {
fPoint triangle[3] = { {-10, -5}, {10, -5}, {0, 5} };
fPoint triangle2[3] = { {-10, -5}, {10, -5}, {0, -5} };
int i = 0;
int collisionCount = 0;
int passes = 0;
while (testing) {
for (int j = 0; j < THREAD_LOAD && testing; j++) {
if (PointInTriangle(points[j], triangle[0], triangle[1], triangle[2])) {
collisionCount++;
}
else if (PointInTriangle(points[j], triangle[0], triangle[1], triangle[2])) {
collisionCount++;
}
i++;
}
passes++;
}
m.lock();
totalCollisions += collisionCount;
totalIterations += i;
totalPasses += passes;
m.unlock();
}
void test3(int rand) {
fPoint* points = new fPoint[THREAD_COUNT * THREAD_LOAD];
std::mt19937 gen(rand);
std::uniform_real_distribution<float> dist(-100.0f, 100.0f);
for (int i = 0; i < THREAD_COUNT * THREAD_LOAD; i++) {
points[i].x = dist(gen);
points[i].y = dist(gen);
}
std::thread* threads[THREAD_COUNT];
testing = true;
totalCollisions = 0;
totalIterations = 0;
totalPasses = 0;
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i] = new std::thread(test3_threaded, points + (i * THREAD_LOAD));
}
Sleep(1000);
testing = false;
for (auto& thread : threads) {
thread->join();
}
std::cout << "iterations: " << totalIterations << std::endl;
std::cout << "collisions: " << totalCollisions << std::endl;
std::cout << "passes: " << totalPasses << std::endl;
}
int main() {
for (int i = 0; i < 5; i ++) test3(i * 13);
return 0;
}
package main
import (
"fmt"
"math/rand"
"sync"
"sync/atomic"
"time"
)
type fPoint struct {
x, y float64
}
func sign(p1 fPoint, p2 fPoint, p3 fPoint) float64 {
return (p1.x-p3.x)*(p2.y-p3.y) - (p2.x-p3.x)*(p1.y*p3.y)
}
func pointInTriangle(pt fPoint, v1 fPoint, v2 fPoint, v3 fPoint) bool {
d1 := sign(pt, v1, v2)
d2 := sign(pt, v2, v3)
d3 := sign(pt, v3, v1)
hasNeg := (d1 < 0 || d2 < 0 || d3 < 0)
hasPos := (d1 > 0 || d2 > 0 || d3 > 0)
return !(hasNeg && hasPos)
}
const (
GO_COUNT = 6
GO_LOAD = 1000
)
func perform3(rs int64) {
rand.Seed(rs)
points := make([]fPoint, GO_COUNT*GO_LOAD)
for i := range points {
points[i] = fPoint{rand.Float64()*200 - 100, rand.Float64()*200 - 100}
}
triangle1 := []fPoint{{-10, -5}, {10, -5}, {0, 5}}
triangle2 := []fPoint{{-10, 5}, {10, 5}, {0, -5}}
var isRunning atomic.Bool
var m sync.Mutex
isRunning.Store(true)
chDone := make(chan bool)
totalIterations := 0
totalCollisions := 0
totalPasses := 0
process := func(start int) {
collisions := 0
iterations := 0
passes := 0
for isRunning.Load() {
for i := start; i < start+GO_LOAD && isRunning.Load(); i++ {
if pointInTriangle(points[i], triangle1[0], triangle1[1], triangle1[2]) {
collisions++
} else if pointInTriangle(points[i], triangle2[0], triangle2[1], triangle2[2]) {
collisions++
}
iterations++
}
passes++
}
m.Lock()
totalCollisions += collisions
totalIterations += iterations
totalPasses += passes
m.Unlock()
chDone <- true
}
for i := 0; i < GO_COUNT; i++ {
go process(i * GO_LOAD)
}
time.Sleep(time.Second)
isRunning.Store(false)
for i := 0; i < GO_COUNT; i++ {
<-chDone
}
fmt.Println("iterations:", totalIterations)
fmt.Println("collisions:", totalCollisions)
fmt.Println("passes:", totalPasses)
}
func main() {
for i := 0; i < 5; i++ {
perform3((int64)(i * 13))
}
}
@XANOZOID
Copy link
Author

The point in triangle code came from here: https://stackoverflow.com/a/2049593/2945133

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment