Topic : C++ Performance
Author : Glen McCluskey & Associates LLC
Page : << Previous 2  Next >>
Go to page :


      // copy a string

};
// constructor
Copy::Copy()

{
        ln = 0;
        maxln = 0;
        vec = 0;
        freelen = 0;
        freestr = 0;

}
// destructor
Copy::~Copy()

{
        int i;

        // delete buffers

        for (i = 0; i < ln; i++)
                delete vec[i];

        // delete vector itself

        if (vec)
                delete vec;

}
// copy a string char* Copy::copy(char* s) {

        int i;
        char** newvec;
        int len;
        char* p;

        assert(s && *s);

        len = strlen(s) + 1;

        // first time or current buffer exhausted?

        if (len > freelen) {
                if (!vec || ln == maxln) {

                        // reallocate vector

                        maxln = (maxln ? maxln * 2 : COPY_VEC);
                        newvec = new char*[maxln];
                        assert(newvec);
                        for (i = 0; i < ln; i++)
                                newvec[i] = vec[i];
                        if (vec)
                                delete vec;
                        vec = newvec;
                }

                // allocate new buffer

                vec[ln] = new char[COPY_BUF];
                assert(vec[ln]);
                freelen = COPY_BUF;
                freestr = vec[ln];
                ln++;
        }

        // allocate and copy string

        freelen -= len;
        p = freestr;
        freestr += len;
        strcpy(p, s);
        return p;

}
#ifdef DRIVER

#include <stdio.h>
#include <alloc.h>



main() {

        long cl;
        const int MAXLINE = 256;
        char buf[MAXLINE];
        FILE* fp;
        char* s;

#ifdef USE_COPY

        Copy co;

#endif


        cl = coreleft();
        fp = fopen("c:/src/words", "r");
        assert(fp);
        while (fgets(buf, MAXLINE, fp) != NULL) {

#ifdef USE_COPY

                s = co.copy(buf);

#else

                s = new char[strlen(buf) + 1];
                assert(s);
                strcpy(s, buf);

#endif

        }
        fclose(fp);
        printf("memory used = %ld\n", cl - coreleft());

        return 0;

}
#endif





Part III
Hidden Constructor/Destructor Costs


Consider a short example of C++ code:


        class A {
                int x, y, z;
        public:
                A();
        };

        class B {
                A a;
        public:
                B() {}
        };

        A::A() {x = 0; y = 0; z = 0;}


Class A has a constructor A::A(), used to initialize three of the class's data members. Class B has a constructor declared inline (defined in the body of the class declaration). The constructor is empty.


Suppose that we use a lot of B class objects in a program. Each object must be constructed, but we know that the constructor function body is empty. So will there be a performance issue?


The answer is possibly "yes", because the constructor body really is NOT empty, but contains a call to A::A() to construct the A object that is part of the B class. Direct constructor calls are not used in C++, but conceptually we could think of B's constructor as containing this code:


        B::B() {a.A::A();}      // construct "a" object in B class

There's nothing sneaky about this way of doing things; it falls directly out of the language definition. But in complex cases, such as ones involving multiple levels of inheritance, a seemingly empty constructor or destructor can in fact contain a large amount of processing.




Part IV
Declaration Statements


Suppose that you have a function to compute factorials (1 x 2 x ... N):


        double fact(int n)
        {
                double f = 1.0;
                int i;
                for (i = 2; i <= n; i++)
                        f *= (double)i;
                return f;
        }


and you need to use this factorial function to initialize a constant in another function, after doing some preliminary checks on the function parameters to ensure that all are greater than zero. In C you can approach this a couple of ways. In the first, you would say:


        /* return -1 on error, else 0 */
        int f(int a, int b)


Page : << Previous 2  Next >>