Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A class rewritten with templates makes a program slower (in run-time)

I have a class for a serial-memory 2D array that was initially an array of ints. Now that I need a similar array with another type, I've rewritten the class with templates; the only difference is in the type of stored objects:

template <class T>
class Serial2DArray
{
    ...
    T ** Content;
}

I have a few test functions that deal with Content, for example, a one that nullifies all elements in the array (they're not class members, they're outside functions working with Serial2DArray<int> objects. I've noticed that now it works 1-2% slower - all the other code in the class is untouched, the only difference is that earlier it was just a regular class with int ** Content and now it's a template.

A sort of similar question: Do c++ templates make programs slow? - has opinions that only compilation becomes slower (and I can see why, the compiler generates classes for each that it finds in the code), but here I see the program becoming slower in run-time - is there any rational explanation?

Upd: issue narrowed down a little bit here: https://stackoverflow.com/a/11058672/1200000

Upd2: as mentioned in the comments, here's the function that became slower:

#include <windows.h>
#include <mmsystem.h>
...
int Size = G_Width * G_Height * sizeof(int);
DWORD StartTime = timeGetTime();
for(int i=0; i<100; ++i)
{
    FillMemory(TestArray.Content[0], Size, 0);
}
MeasuredTime = timeGetTime() - StartTime;

And here's the actual class template:

#include <malloc.h>

template <class T>
class Serial2DArray
{
    public:
    Serial2DArray()
    {
        Content = NULL;
        Width = 0;
        Height = 0;
    }
    Serial2DArray(int _Width, int _Height)
    {
        Initialize(_Width, _Height);
    }
    ~Serial2DArray()
    {
        Deinitialize();
    }
    T ** Content;
    int GetWidth()
    {
        return Width;
    }
    int GetHeight()
    {
        return Height;
    }
    int Initialize(int _Width, int _Height)
    {
        // creating pointers to the beginning of each line
        if((Content = (T **)malloc(_Height * sizeof(T *))) != NULL)
        {
            // allocating a single memory chunk for the whole array
            if((Content[0] = (T *)malloc(_Width * _Height * sizeof(T))) != NULL)
            {
                // setting up line pointers' values
                T * LineAddress = Content[0];
                for(int i=0; i<_Height; ++i)
                {
                    Content[i] = LineAddress; // faster than Content[i] =
                    LineAddress += _Width;    // Content[0] + i * _Width;
                }
                // everything went ok, setting Width and Height values now
                Width = _Width;
                Height = _Height;
                // success
                return 1;
            }
            else
            {
                // insufficient memory available
                // need to delete line pointers
                free(Content);
                return 0;
            }
        }
        else
        {
            // insufficient memory available
            return 0;
        }
    }
    int Resize(int _Width, int _Height)
    {
        // deallocating previous array
        Deinitialize();
        // initializing a new one
        return Initialize(_Width, _Height);
    }
    int Deinitialize()
    {
        // deleting the actual memory chunk of the array
        free(Content[0]);
        // deleting pointers to each line
        free(Content);
        // success
        return 1;
    }
    private:
    int Width;
    int Height;
};

As requested, binaries size comparison.

Code with the following:

Serial2DArray<int> TestArray; 
Serial2DArray<int> ZeroArray;
  • 1 016 832 bytes.

Code with the following:

Serial2DArray TestArray; // NOT-template class with ints
Serial2DArray ZeroArray; // methods are in class declaration
  • 1 016 832 bytes

Code with the following:

Serial2DArray<int> TestArray;
Serial2DArray<int> ZeroArray;
Serial2DArray<double> AnotherArray;
Serial2DArray<double> YetAnotherArray;
  • 1 017 344 bytes
like image 943
Fy Zn Avatar asked Nov 21 '25 01:11

Fy Zn


1 Answers

Yeah- random benchmark variability, not to mention the fact that the whole program is slower might have nothing at all to do with this specific class.

like image 85
Puppy Avatar answered Nov 22 '25 16:11

Puppy