29

I'm trying to decide which to learn and I've read all the "Which is better" questions/arguments, so I thought I'd get your take on something more specific.

Is there a platform dependency issue that C++ developers run into with such applications? Or, is it because there are more C developers out there than C++? I also noticed that many more third party C modules exist for Python even thought C++ modules are supported. From what I've read on different threads the consensus is that C++ is easier and faster to write, and runs just as fast. Am I missing something really big.

Examples:

NGINX APE (comet server) Apache

32 accepted

Edit: Due to the extremely subjective nature of comparing programming languages, in particular the open hostility many in the C and C++ camps have towards each other, I would like to make it absolutely clear that I am attempting to explain a point of view rather than champion one language over the other.

  1. Fast servers try to minimize the amount of copying done. This means that any strings you parse out of an IO buffer are represented using pointers. Using std::string would mandate copying the string, which is slow. You could create a new string class which doesn't copy its contents, but this string class would be no better than a C structure. Edit: Sometimes, modifying code to use C++ structures will require either additional copying, additional indirection, or writing the code in the same manner as the C code. For example, std::list<T> will copy any T that you add to it, while std::list<T*> requires an additional object for each member and has an additional layer of indirection. The least expensive option might be to put next and prev fields inside the T structure itself. I think Boost has a library for handling this case, but linked lists are second nature to experienced C programmers so there's not a huge benefit to the Boost option and some programmers stylistically prefer handling linked lists themselves. Some of the people commenting below suggested that passing a std::string& or my_string& is as cheap as passing around pointers to a buffer ? this is not entirely true, since in order to access the buffer one now has to dereference two pointers, where the C code would only have to dereference one. The differences vanish if my_string is passed by value, as long as it doesn't do anything too fancy in its copy constructor... however, such an object would no longer be any safer than the equivalent C construct (since in this case, my_string can now outlast the buffer to which it points).

  2. Fast servers try to minimize the amount of allocation done. So while a programmers are writing fast servers, it helps if none of the allocations and deallocations are hidden from view. This means that all of those helpful ways to make allocations unobtrusive in C++ get in the way. Edit: A smart C++ programmer will be very aware of where the code performs allocations. Nonetheless, a C programmer doesn't have to think quite so hard about it.

  3. Fast servers need to work with syscalls very closely, and keep data in the format that the syscalls expect whenever possible. Syscalls have a C interface. Edit: It's very easy to call them from C++, too, but wrapping all of the objects in C++ classes is a lot of work for not much benefit.

  4. Exception handling causes code size to increase. This decreases the locality of the program code and slows it down, even if no exceptions are being thrown. Edit: I am aware that this is a negligible (but measurable) difference in speed. I've heard the difference in executable size is something like 5-15%, which matches the results I got using quick tests with and without -fno-exceptions using g++. I'd say it's more relevant that some of these servers use a somewhat unusual error handling technique: if code is handling a request and there's an error, you can just jump out to an outermost error handling routine and let it handle cleanup. If you're using memory pools, such as Apache's apr_pool_t, then there's no need to call destructors as you unwind the stack and therefore the advantages of C++ exceptions over longjmp are somewhat few.

  5. Template instantiations cause code size to skyrocket. This also decreases the locality of the program code. Edit: The instantiations are exactly what give C++ templates their speed advantage over near-equivalent C code. For example, if you want to sort an array of X, you can get a fully inlined, rock-solid sorting function in C++ using templates in a single line of code. In C, you would have to write it yourself. But these servers do not use very many different kinds of data structures, often they only need some simple queues and an associative map from strings to void*.

  6. It is relatively easy to estimate how long it will take a particular piece of C code to run, it is more difficult to estimate the run time for C++ code. There are a lot of extra things that can happen in C++ code: temporary objects can be created to pass between functions, operators can be overloaded to perform complex tasks, and exiting a scope can cause expensive destructors to run. I've seen C++ programs hang in poorly written destructors. On the other hand, C maps very cleanly to machine code, with relatively few surprises.

  7. (Edit: new) There's also the issue of the performance compiling a given piece of code using a C compiler versus compiling it with a C++ compiler. Due to the stricter aliasing rules of C++, the performance benefit often goes to the code compiled with the C++ compiler. However, C99 has introduced the new restrict keyword which is not yet available in C++. It allows the user to declare that there are no active aliases to a given region of memory. This allows the compiler to perform some types of optimizations previously only available to Fortran programmers (as Fortran has stricter aliasing rules than C++).

So, if you were trying to write a very high performance server in C++, you'd probably not use the STL, exceptions, templates (or sparingly), sophisticated constructors or destructors, or operator overloading. You'd also probably not wrap the C structures you use. What are you left with? You're left with 90% C and 10% C++. At this point, you say, "why bother?" and write the whole thing in C. There are added benefits to using C:

  • C compilers are available in places where C++ compilers are not. On some platforms, C++ compilers are available but not as mature as the C compiler. Conditions were worse in 1995, which was when Apache was written.

  • If you write your app in C, people can write glue to call into their favorite dynamic language (Python, Ruby, Perl) without much trouble. It is easier to interface with those languages if your application is written in C.

I think the biggest part of it all is the syscalls. When designing a fast server, you basically plan how the bytes travel from one syscall to another syscall as quickly as possible. I would guess that high performance non-server apps that do more number crunching are more likely to be written in C++, for example, many fast AI libraries seem to be written in C++.

Edit: There's also a sampling error here. The projects listed are open-source projects only, and certain parts of the open-source community, especially the systems programming part, use C. Part of this is cultural, as perhaps the most visible open-source project is the Linux kernel, which is written in C. Linus Torvalds in particular is noted for his rants against C++, you can also look at the Linux kernel mailing list FAQ with a section on why Linux does not support C++ in the kernel. The Linux kernel has some even better reasons not to use C++, especially that exception handling in kernel code is generally regarded as a very bad idea (Apple's IOKit, which requires you to write drivers in C++, disables exception handling). I would say that C is much less common outside of the open-source community.

As for Python modules, most of the ones written in C are just interfaces to some other library (and a large portion of these modules are written in Python itself, natch). Most of the C code is spent converting between the formats that the library expects and formats that Python can understand. C++ doesn't deliver any real benefits for this kind of glue code. Fortunately, the glue code is very small (I wouldn't want to write very much of it).

As for a recommendation about which to learn: The nicest thing about programs like nginx, varnish, apache, git, subversion, python, etc. is that they're already written and already ready for a production environment. I would definitely not recommend either C or C++ over the other unless I knew what kind of applications you wanted to write, as I'm guessing you're not going to write the next web server (we already have a good selection).

11

This is my guess, as such nothing taken from any source. C has been around a long time. Programmers have been around a long time. The most experienced programmers are probably old. Maybe some of the really fast servers have been around a long time too? I am just thinking age + refactoring + experience (over time) = fast servers :). I am thinking some products started out when C was "the hot language" and have been maintained since.

Any product that gets popular benefits from maintainance to keep/grow popularity, I guess.

I don't think it's something that happens over night.

11

I strongly suspect that this has more to do with a lack of C++ APIs for network I/O at the time they were written than anything else; the socket(), bind(), listen(), accept(), select(), read(), and write() system calls all have C interfaces. While there are now a number of C++ APIs for performing network I/O (e.g. Boost.Asio), these are fairly new to my understanding, and ultimately they simply wrap the C language system calls.

5
  • Software gets faster when it's fine-tuned, and the more boxes software runs on the more fine-tuning gets performed.

  • historically, it's been harder to write portable C++ than C, so widely-used servers were written in C for portability.

  • so, those were the software that got more tuning effort.

5

To me what you're talking about seems to be Open Source servers, not servers in general. I have seen servers written in C++, but this was in the industry, not in the Open Source community. I think C++ is much more used in the industry than it is in the Open Source community.

IME a very important reason why so much of the Open Source software is written in C instead of C++ is that some of their most glorious figures don't like C++. An often cited example is Linus Torvalds dissing C++. While this has often been well countered (see here for a nice example), it nevertheless has a great influence.

Another reason is that C compilers are much easier to write than C++ compilers (and we're probably talking orders of magnitude here), which is why C is indeed somewhat more portable than C. However, GCC's abundance has rendered systems where C is available, but C++ isn't, a niche.

Finally, I believe that, if you know too little about both languages, while it is much easier to write safer code in C++, it is easier to write fast code in C. (And don't you dare to ever cite this without the highlighted disclaimer!) However, if you're an experienced C++ programmer, it is much easier to write fast and bug free code in C++ than it is in C.

4

I strongly belive, many C programs should run identical speed when translated with either the C and with the C++ compiler , this is because C programs are valid C++ programs when the features of either not considered.

Although when the features of C++ are to be considered here, C++ only makes simpler and less error prone.

I agree with @Statement statement that , it could be because C has been since long and most people very much comfortable writing C programs.

I myself started with C and moving to C++ programs , I feel C++ provides no significant downsides and a number of significant improvements making your program easy to maintain with less error prone. But I do feel at times there is many concepts to learn to master C++ and I have to run here and there to find best solution [This is one place off course], whilst working on C I hardly referred any document or ask people for help.

2

Why are most really fast servers written in C instead of C++?

What do you mean by server?

I have no understanding of what you mean by 'really fast'?

Can you quantify 'most'?

How do you know that 'most really fast servers' are written in C?

What criteria did you have in mind when formulating this question?

A server's networking code may be written in C but it's primary function of accessing a database may not be written in C.

So many hidden assumptions here.

I feel like I'm trying to elicit formal requirements from a customer. -:)

I predict that I'll get down voted for being pedantic!

1

I think it's hard to hit a moving target, especially if you're trying to write a program that is fast, simple and cross-platform. C is a smaller, less complex language than C++, and C has not changed very much since in the mid-1990s as the Internet was ramping up. C++ is coming out with C++0X sometime in 2011 supposedly, so the language is still evolving.

1

Dunno about nginx, and this might not be the answer you're looking for, but you could find a somewhat educating discussion/bit of speculation on why Apache uses C instead of C++ here.

0

Hysterical reasons.

You can write fastest possible code while still expressing abstractions as C++ classes. Also, template metaprogramming techniques enable some performance optimizations not possible in C, such as custom loop unrolling.

-1

There is no appreciable difference in speed from a good C++ coder Vs a good C coder, unless you are writing bank trading software or something where every 0.001s in executing a trade can get extra money.

Both languages are very fast and even C++ is considered low-level and not optimal for writing most software... typically the decision would be between C++/Java or C++/C#, not C/C++.

C is good to learn, but C++ is likely to be far more useful to you... and if you know C++ you can quite easily work on pure C code if you ever need to.

C is historically used a lot in the Linux world, partly because people like Torvalds (Linux creator) don't personally like C++ and are hugely influential. It's mostly a social effect - by contrast on Windows C++ is much more popular.

Considering C++ is being viewed as old-fashioned, and C is slowly being replaced even in embedded systems by C++, C++ is clearly the right choice in my view. And then learn Java.