Created
March 4, 2023 15:00
-
-
Save abar193/14479b8683cf46fed2c0a1958e6e1d14 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cstdio> | |
#include <cmath> | |
typedef float f32; | |
typedef unsigned int u32; | |
const float Pi32 = 3.14159265; | |
const int SHAPES = 100500; | |
const int ITERATIONS = 1000; | |
// clean | |
class shape_base | |
{ | |
public: | |
shape_base() {} | |
virtual f32 Area() = 0; | |
}; | |
class square : public shape_base | |
{ | |
public: | |
square(f32 SideInit) : Side(SideInit) {} | |
virtual f32 Area() {return Side*Side;} | |
private: | |
f32 Side; | |
}; | |
class rectangle : public shape_base | |
{ | |
public: | |
rectangle(f32 WidthInit, f32 HeightInit) : Width(WidthInit), Height(HeightInit) {} | |
virtual f32 Area() {return Width*Height;} | |
private: | |
f32 Width, Height; | |
}; | |
class triangle : public shape_base | |
{ | |
public: | |
triangle(f32 sideA, f32 sideB, f32 sideC) : sideA(sideA), sideB(sideB), sideC(sideC) {} | |
virtual f32 Area() { | |
f32 p = (sideA + sideB + sideC) / 2; | |
return sqrt(p * (p - sideA) * (p - sideB) * (p - sideC)); | |
} | |
private: | |
f32 sideA, sideB, sideC; | |
}; | |
class circle : public shape_base | |
{ | |
public: | |
circle(f32 RadiusInit) : Radius(RadiusInit) {} | |
virtual f32 Area() {return Pi32*Radius*Radius;} | |
private: | |
f32 Radius; | |
}; | |
f32 TotalAreaVTBL(int ShapeCount, shape_base **Shapes) | |
{ | |
f32 Accum = 0.0f; | |
for(int ShapeIndex = 0; ShapeIndex < ShapeCount; ++ShapeIndex) | |
{ | |
Accum += Shapes[ShapeIndex]->Area(); | |
} | |
return Accum; | |
} | |
shape_base** generateShapes(int count) { | |
shape_base** base = static_cast<shape_base **>(malloc(count * sizeof(shape_base *))); | |
for(int i = 0; i < count; i++) { | |
int shape = rand() % 3; | |
if(shape == 0) { | |
base[i] = new square(rand()); | |
} else if(shape == 1) { | |
base[i] = new rectangle(rand(), rand()); | |
} else if(shape == 2) { | |
base[i] = new triangle(rand(), rand(), rand()); | |
} | |
} | |
return base; | |
} | |
void destroyShapes(int size, shape_base** base) { | |
for(int i = 0; i < size; i++) { | |
free(base[i]); | |
} | |
free(base); | |
} | |
// switch | |
enum shape_type : u32 | |
{ | |
Shape_Square, | |
Shape_Rectangle, | |
Shape_Triangle, | |
Shape_Circle, | |
Shape_Count, | |
}; | |
struct shape_union | |
{ | |
shape_type Type; | |
f32 Width; | |
f32 Height; | |
f32 Side; | |
}; | |
f32 GetAreaSwitch(shape_union Shape) | |
{ | |
f32 Result = 0.0f; | |
switch(Shape.Type) | |
{ | |
case Shape_Square: {Result = Shape.Width*Shape.Width;} break; | |
case Shape_Rectangle: {Result = Shape.Width*Shape.Height;} break; | |
case Shape_Triangle: { | |
f32 p = (Shape.Width + Shape.Height + Shape.Side) / 2; | |
Result = sqrt(p * (p-Shape.Width) * (p - Shape.Height) * (p - Shape.Side)); | |
} break; | |
case Shape_Circle: {Result = Pi32*Shape.Width*Shape.Width;} break; | |
case Shape_Count: {} break; | |
} | |
return Result; | |
} | |
f32 TotalAreaSwitch(u32 ShapeCount, shape_union *Shapes) | |
{ | |
f32 Accum = 0.0f; | |
for(u32 ShapeIndex = 0; ShapeIndex < ShapeCount; ++ShapeIndex) | |
{ | |
Accum += GetAreaSwitch(Shapes[ShapeIndex]); | |
} | |
return Accum; | |
} | |
shape_union* generateShapesSwitch(int count) { | |
shape_union* base = static_cast<shape_union *>(malloc(count * sizeof(shape_union))); | |
for(int i = 0; i < count; i++) { | |
int shape = rand() % 3; | |
if(shape == 0) { | |
base[i].Type = Shape_Square; | |
base[i].Width = rand(); | |
} else if(shape == 1) { | |
base[i].Type = Shape_Rectangle; | |
base[i].Width = rand(); | |
base[i].Height = rand(); | |
} else if(shape == 2) { | |
base[i].Type = Shape_Triangle; | |
base[i].Width = rand(); | |
base[i].Height = rand(); | |
base[i].Side = rand(); | |
} | |
} | |
return base; | |
} | |
void destroyShapesSwitch(int size, shape_union* base) { | |
free(base); | |
} | |
// table, union or whatever | |
f32 const CTable[Shape_Count] = {1.0f, 1.0f, 0.5f, Pi32}; | |
f32 GetAreaUnion(shape_union Shape) | |
{ | |
if(Shape.Type == Shape_Triangle) { | |
f32 p = (Shape.Width + Shape.Height + Shape.Side) / 2; | |
return sqrt(p * (p - Shape.Width) * (p - Shape.Height) * (p - Shape.Side)); | |
} | |
return CTable[Shape.Type]*Shape.Width*Shape.Height; | |
} | |
f32 TotalAreaUnion(u32 ShapeCount, shape_union *Shapes) | |
{ | |
f32 Accum = 0.0f; | |
for(u32 ShapeIndex = 0; ShapeIndex < ShapeCount; ++ShapeIndex) | |
{ | |
Accum += GetAreaUnion(Shapes[ShapeIndex]); | |
} | |
return Accum; | |
} | |
// display | |
double calcAvg(double arr[]) { | |
double s = 0; | |
for(int i = 0; i < ITERATIONS; i++) { | |
s += arr[i] / ITERATIONS; | |
} | |
return s; | |
} | |
int main() { | |
std::cout << "Hello, World!" << std::endl; | |
double timeClean[ITERATIONS], timeSwitch[ITERATIONS], timeUnion[ITERATIONS]; | |
clock_t start, end; | |
shape_base** base = generateShapes(SHAPES); | |
shape_union* baseSwitch = generateShapesSwitch(SHAPES); | |
for(int i = 0; i < ITERATIONS; i++) { | |
start = clock(); | |
/*std::cout << */TotalAreaVTBL(SHAPES, base);// << std::endl; | |
end = clock(); | |
double time_taken = double(end - start) / double(CLOCKS_PER_SEC); | |
timeClean[i] = time_taken; | |
} | |
for(int i = 0; i < ITERATIONS; i++) { | |
start = clock(); | |
TotalAreaUnion(SHAPES, baseSwitch);// << std::endl; | |
end = clock(); | |
double time_taken = double(end - start) / double(CLOCKS_PER_SEC); | |
timeUnion[i] = time_taken; | |
} | |
for(int i = 0; i < ITERATIONS; i++) { | |
start = clock(); | |
TotalAreaSwitch(SHAPES, baseSwitch);// << std::endl; | |
end = clock(); | |
double time_taken = double(end - start) / double(CLOCKS_PER_SEC); | |
timeSwitch[i] = time_taken; | |
} | |
double cleanTime = calcAvg(timeClean); | |
double switchTime = calcAvg(timeSwitch); | |
double unionTime = calcAvg(timeUnion); | |
printf("Clean approach: %.5f\n", cleanTime); | |
printf("Switch approach: %.5f (%.5f)\n", switchTime, cleanTime / switchTime); | |
printf("Union approach: %.5f (%.5f)\n", unionTime, cleanTime / unionTime); | |
destroyShapes(SHAPES, base); | |
destroyShapesSwitch(SHAPES, baseSwitch); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment