Live data from Hacker News

Comparing C and C++ usage and performance with a real world project

nibblestew.blogspot.com

101–110 of 140 posts

Re: Comparing C and C++ usage and performance with a real world project

#101
"The C++ version has no pointers but instead uses value types. This means that all data is stored twice: once in the array and a second time in the hash table."

This is interesting. Are they using modern C++ and making use of moves and perfect forwarding? Or are they just throwing std::strings around and doing millions of copies (e.g. remember std::vector must support copyconstructable, so copy constructors & operator=) in the process? That would explain the allocations in C++ being higher perhaps, particularly if they're using the "wrong" containers. Why not sure unique_ptr or shared_ptr?

It is worth remembering that move constructors and assignment operators only get used in very specific places and you have to ensure that any constructors you write yourself are explicitly noexcept.

Re: Comparing C and C++ usage and performance with a real world project

#102
post #70

Earlier quoted context omitted.

Template instantiation surely only requires type substitution and re-running some analysis though. What makes C++ compilation slow is reparsing headers again and again and again because the C the preprocessor means that every time they are encountered they may have new semantics. The motivation for modules in C++ is similar to that of developing a Binary AST for Javascript, discussed on HN recently.

If modules ever happen, wow, C++ is going to feel like a whole new language. I remember large Pascal codebases compiling in as little time as it took to press the key, and this was in the era of computers with mere megabytes of memory. Turbo C++ was never as "turbo" as Turbo Pascal.

That's probably not just modules though. Pascal, being one of Niklaus Wirth's languages, was specifically designed to be easy to compile, generally not even requiring building an AST (though a particular compiler still might, especially of it added extensions to the language).

Re: Comparing C and C++ usage and performance with a real world project

#103
post #40
post #26

Earlier quoted context omitted.

I have heard of calculating a "memory budget" and pre-allocating that, but calculating a "leak budget" and doubling that doesn't seem like hygienic programming.

Doesn't have to be hygienic, it's enough that fixing it doesn't justify the time/money costs for the programmer.

We wouldn't want the programmer to spend too much money/time on fixing errors. After all, it's not like people would die if there's an error in the missile software: http://www.gao.gov/mobile/products/IMTEC-92-26

Not to mention they added even more HW to work around the leaks. No wonder those projects always run over budget.

Re: Comparing C and C++ usage and performance with a real world project

#104
post #45

Earlier quoted context omitted.

> a C++ class is like a C struct that can contain function pointers. No, it's not. Calling an ordinary class member function in C++ has exactly the same overhead as calling a function in C. Even virtual functions in C++ are not the same as putting function pointers in a C struct (they live in a separate data structure called the vtable). > the protection mechanisms and the class heirarchy All C++ protection mechanism…

Doesn't a vtable imply an extra level of indirection? You have to find where the vtable is in the object, then the function within the vtable, right? Is that not slower?

In common implementations the vtable pointer is always the first word inside the object. Given an arbitrary pointer to an object, the offset of this vtable pointer relative to what you're pointing to is always computed statically at compile time. Unless you're using multiple inheritance, this offset is usually zero because derived object pointers in a single-inheritance hierarchy actually always point to their base.

If you're using multiple inheritance then an object can have multiple vtable pointers, but again which one you need to use is known at compile-time based on which class the virtual function you're calling is declared within, and the type of pointer you have.

Once you have the vtable you then have to locate the function pointer for the function you're calling. Again, this is usually a compile-time constant offset from the start of the vtable. This ceases to be true when you have 'virtual inheritance' (not to be confused with virtual functions), when another indirection to find this function pointer is required.

Here are some examples:

https://godbolt.org/g/N2XcV7

You'll notice that the get_square() function, which returns a member function pointer to the virtual square function, doesn't even return any memory addresses, just metadata and an offset

Re: Comparing C and C++ usage and performance with a real world project

#105
post #99
post #70

Earlier quoted context omitted.

Template instantiation surely only requires type substitution and re-running some analysis though. What makes C++ compilation slow is reparsing headers again and again and again because the C the preprocessor means that every time they are encountered they may have new semantics. The motivation for modules in C++ is similar to that of developing a Binary AST for Javascript, discussed on HN recently.

> What makes C++ compilation slow is reparsing headers again and again and again because the C the preprocessor means that every time they are encountered they may have new semantics. Really? And I thought that this is why C and C++ headers are typically wrapped in #ifndef-#define-#endif block, so they only produce whitespace after preprocessing on second inclusion.

Yes, this happens inside a single translation unit (.cpp file). However if you have multiple .cpp files which include the same header file you have to reparse it each time. This is because before the inclusion of that header different #defines might have been set (e.g. through other headers), and therefore the content of the header file might be different.

Re: Comparing C and C++ usage and performance with a real world project

#106
post #99
post #70

Earlier quoted context omitted.

Template instantiation surely only requires type substitution and re-running some analysis though. What makes C++ compilation slow is reparsing headers again and again and again because the C the preprocessor means that every time they are encountered they may have new semantics. The motivation for modules in C++ is similar to that of developing a Binary AST for Javascript, discussed on HN recently.

> What makes C++ compilation slow is reparsing headers again and again and again because the C the preprocessor means that every time they are encountered they may have new semantics. Really? And I thought that this is why C and C++ headers are typically wrapped in #ifndef-#define-#endif block, so they only produce whitespace after preprocessing on second inclusion.

It's not the second inclusion that's a problem but the way any given template might behave completely differently depending on what order they're loaded in.

That is, including a, b, c is not necessarily the same as a, c, b or b, a, c. This is not true with proper modules, they're order invariant, and as such you can make a ton of optimiztions.

Re: Comparing C and C++ usage and performance with a real world project

#107
post #71

Earlier quoted context omitted.

Can you clarify what runtime needs would a class hierarchy have in C++ that a correctly structured C program wouldn't have?

Well, if you override the implementation of a function in a subclass, the runtime has to determine that and load it in at runtime, when you instantiate an object of the subclass. In C there is no runtime.

This is done at compile time. The call is indirect, which only means the call destination is decoupled from the generated calling code. This does not entail the runtime loading anything.

http://www.geeksforgeeks.org/virtual-functions-and-runtime-p...

Re: Comparing C and C++ usage and performance with a real world project

#108
post #88

Earlier quoted context omitted.

Doesn't a vtable imply an extra level of indirection? You have to find where the vtable is in the object, then the function within the vtable, right? Is that not slower?

Yes, although (cache behavior notwithstanding) it's a single pointer indirection that can frequently be optimized away by the compiler.

My point is simply this -- adding protection mechanisms and inheritance to classes neccesitates adding more complexity to the structure used to represent them (such as a vtable) which does add performance overheads. If you dont need those features, you can go leaner and faster with a C structure that includes function pointers to give you the basic packaging of data and functions that an object has.

Re: Comparing C and C++ usage and performance with a real world project

#109
post #107

Earlier quoted context omitted.

Well, if you override the implementation of a function in a subclass, the runtime has to determine that and load it in at runtime, when you instantiate an object of the subclass. In C there is no runtime.

This is done at compile time. The call is indirect, which only means the call destination is decoupled from the generated calling code. This does not entail the runtime loading anything. http://www.geeksforgeeks.org/virtual-functions-and-runtime-p...

OK. Wouldn't that indirection add an extra instruction, each time you called a function?

Re: Comparing C and C++ usage and performance with a real world project

#110

Earlier quoted context omitted.

Well, some parts of the generative programming could be built into a tool and you probably wouldn't have to rewrite a generative program each time. So it's not really writing in 2 languages but using code generation to assist the programming process to reduce potential for error as a more flexible alternative to creating fixed constructs in a purpose built language.

You can get 90% of that benefit by using snippets in your favorite editor. I guess you could consider that "code generation", but "generative programming" means, to me, "check in the specification, not the production code".

You're assuming gnerative programming is used to completely replace direct programming. This doesn't have to be the case. It could also be used merely in an assistive role to supplement the ability to write code.
Post reply on HN