DEV Community

Discussion on: Exploring the Use of C++ for Game Development

 
plotarmouredtitan profile image
PlotArmouredTitan • • Edited

This is a version that uses std::allocator to pre-allocate memory before later constructing it for usage

#include "stdio.h"
#include "stdlib.h"
#include <chrono>
#include <iostream>
#include <string>
#include <memory>

class Person {
public:
    int age;
    Person(int age)
    {
        this->age = age;
    }
};

auto time_ms()
{
    return std::chrono::high_resolution_clock::now();
}

int run(int r, int s) {
    auto start = time_ms();
    int e = 0;

    for (int i = 0; i < r; i++) {
        Person* p = new Person(s);
        e += p->age;
        delete p; // only to avoid `out of memory` error
        // in fact, `delete` improves performance here
        // almost twice
    }
    auto end = time_ms();
    auto took = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    printf("Took : %lld ms  ", took.count());
    return took.count();
}

int run_alloc(int r, int s) {

    auto start = time_ms();

    std::allocator<Person> alloc;
    //allocate memory pool
    Person * memPool = alloc.allocate(r);

    int e = 0;

    for (int i = 0; i < r; i++) {
        //retrieve address from memory pool
        Person* p = memPool + i;

        //construct object
        alloc.construct(p, s);

        e += p->age;

        //destroy object
        alloc.destroy(p);
    }

    //deallocate memory pool
    alloc.deallocate(memPool, r);

    auto end = time_ms();
    auto took = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    printf("Alloc method Took : %lld ms\n", took.count());
    return took.count();
}
int run_alloc_reused(int r, int s) {

    auto start = time_ms();

    std::allocator<Person> alloc;
    Person* memAddr = alloc.allocate(1);

    int e = 0;

    for (int i = 0; i < r; i++) {
        Person* p = memAddr;

        alloc.construct(p, s);

        e += p->age;

        alloc.destroy(p);
    }

    alloc.deallocate(memAddr, r);

    auto end = time_ms();
    auto took = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    printf("Reused Alloc method Took : %lld ms\n", took.count());
    return took.count();
}


int main(int argc, char** argv) {

    /*
    int r = atoi(argv[1]);
    int s = atoi(argv[2]);

    printf("Inputs : %d %d\n", r, s);
    printf("Integer type size : %ld\n", sizeof(int));

    */

    int shouldRun = 1;

    while(shouldRun)
    {
        int r = 0;
        int s = 0;

        std::cout << "input r" << '\n';
        std::cin >> r;
        std::cout << "input s" << '\n';
        std::cin >> s;

        long long sum = 0;
        long long min = 1L << 32U;
        long long max = -1;

        long long sum2 = 0;
        long long min2 = 1L << 32U;
        long long max2 = -1;

        int ts = 10;
        for (int i = 0; i < ts; i++) {
            long long t = run(r, s);
            long long t2 = run_alloc(r, s);

            if (t < min) min = t;
            if (t > max) max = t;
            sum += t;

            if (t2 < min2) min2 = t2;
            if (t2 > max2) max2 = t2;
            sum2 += t2;
        }
        double avg = ((double)sum) / ts;
        double avg2 = ((double)sum2) / ts;
        printf("Min : %lld, max : %lld, average : %f\n", min, max, avg);
        printf("Min2 : %lld, max2 : %lld, average2 : %f\n", min2, max2, avg2);

        std::cout << "input 0 to exit, 1 to continue" << '\n';
        std::cin >> shouldRun;
    }
}
Enter fullscreen mode Exit fullscreen mode

Some other changes I made to the code

  • used std::chrono for measuring time because its cross-platform while the method you used was not

  • used std::iostream to handle inputing values at startup time instead of using main() arguments

Edit:made some corrections to the code

Edit2: also I think that allocation and deallocation shouldn't even be included in the time measurement since GC allocations and deallocations are likely done at startup time

Thread Thread
 
taqmuraz profile image
Taqmuraz •

Sorry, I wasn't online. I appreciate your efforts, I am already reading your code

Thread Thread
 
taqmuraz profile image
Taqmuraz •

Case with 'std::allocator' looks better than others, because it has abstraction over test case. I must test how fast it is and compare with other allocation tests. Probably I will update contents of my article. Thank you again for your code :)