5

So far I have only done personal projects at home. I hope to get involved in some open source project some time next year. The languages I that have been using the most are C and C++. I have used both languages for over a year and I feel like I have become quite proficient with both of them, but I really don't know which one I like better.

I personally like C because I think it is simple and elegant. To me C++ seems bloated many unnecessary features that just complicates the design process. Another reason to why I like to use plain C is because it seems to be more popular in the free and open-source software world.

The feature that I miss the most from C++ when I use plain C is probably the std::vector from STL (Standard Template Library).

I still haven't figured out how I should represent growing arrays in C. Up to this point I duplicated my memory allocation code all over the place in my projects. I do not like code duplication and I know that it is bad practice so this does not seems like a very good solution to me.

I thought about this problem yesterday and came up with the idea to implement a generic vector using preprocessor macros.

It looks like this:

int main()
{
    VECTOR_OF(int) int_vec;
    VECTOR_OF(double) dbl_vec;
    int i;

    VECTOR_INIT(int_vec);
    VECTOR_INIT(dbl_vec);

    for (i = 0; i < 100000000; ++i) {
        VECTOR_PUSH_BACK(int_vec, i);
        VECTOR_PUSH_BACK(dbl_vec, i);
    }

    for (i = 0; i < 100; ++i) {
        printf("int_vec[%d] = %d\n", i, VECTOR_AT(int_vec, i));
        printf("dbl_vec[%d] = %f\n", i, VECTOR_AT(dbl_vec, i));
    }

    VECTOR_FREE(int_vec);
    VECTOR_FREE(dbl_vec);

    return 0;
}

It uses the same allocation rules as std::vector (the size starts as 1 and then doubles each time that is required).

To my surprise I found out that this code runs more than twice as fast as the same code written using std::vector and generates a smaller executable! (compiled with GCC and G++ using -O3 in both cases).

My question is:

  • Would you recommend using this in a serious project?
  • If not then I would like you to explain why and what a better alternative would be.
6
  • Smaller executable doesn't surprise me (though I would expect it to worsen as the programs grows larger) but higher speed seems fishy assuming GCC's inlining heuristics are tuned well. Can you show the definitions of the macros and how you benchmark it?
    – user7043
    Commented Dec 30, 2014 at 13:18
  • @delnan Where should I put it? I think the header is too large to put in the question. I can make another question on stackoverflow asking how this implementation can be faster but I don't have time for that now. I can do it later.
    – wefwefa3
    Commented Dec 30, 2014 at 13:27
  • Are those five macros really that large? Regardless, a SO question about the performance seems sensible, then this site can focus on semi-technical reasons besides performance.
    – user7043
    Commented Dec 30, 2014 at 13:35
  • 2
    I personally like this approach and have used similar code. The client core looks neater since you get rid of a lot of casts you would need if you had a vector of void*, the only generic type in C. There are also other advantages, such as debug bounds checking that you can add to VECTOR_AT. The main disadvantage, in my view, is the macro-based code, which is a pain to write and maintain.
    – glampert
    Commented Dec 30, 2014 at 17:22
  • "Serious project" usually means that other people will work on your code at some point. Then readability and familiarity often become more important than speed and size. Unless you all agree on using your VECTOR everywhere, I (regretfully) recommend standardized solution (std or boost)
    – Agent_L
    Commented Dec 31, 2014 at 14:15

1 Answer 1

2

My question is: Would you recommend using this in a serious project?

Yes! Here is something that is mostly true about library functions: they necessarily have to be generally applicable in order to accommodate many users with different requirements. If you know the underlying algorithm, the library function is going to be larger and slower than your own implementation. Most of the time we don't care, because size and speed aren't an issue. However once speed does become an issue and the bottleneck is the library function (very often with library sorting algorithms), simply understanding the algorithm and writing something that works for you can result in dramatic speed improvements. I understand you discovered this in another way (reproducing a feature from std::vector in C) and aren't asking an optimization question. But it's worth mentioning that what you've learned will come in very handy in the future when working in Java, C++, etc. and you run into a speed bottleneck that crushes your project. This can happen often in computationally-intensive projects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.