Hello all!
I am interested in your opinion about what server-based application technology shall I choose. My doubts are between Java and C++. What I have to do is a server-based application with multiple connections and what I need is rapidity in query processing, this is really a vital part of everything.
The main factors for comparison are:
• Network communication via unix socketing;
• Ease of DataBase management (Since now I have chosen Firebird due to the agile license);
• Internal application data structures
In one hand, Java is pretty easy to me and I would be much more productive than in C++. Furthermore, I read that with the latest versions of Frameworks, languages(e.g. Java 6), etc, the difference in rapidity has been reduced to not more than 15%.
So, my question is, does it worth the efforts to do it the hard, but qualitative way, in C++, or I can use Java without worries and achieve the same effect with less resources, without losing quickness in query processing. I would like to choose the right technology and architecture, so I am not soon or later going to be sorry for my choice, when I face a problem, which is not offered a solution by the technology I use.
What do you think?
Penko
Comparison of Java and C++ for server-based application
Started by penkomitev, Oct 01 2009 02:26 AM
38 replies to this topic
|
|
|
#2
Posted 01 October 2009 - 11:55 AM
It depends on a lot of things you HAVEN'T said.
1) will that 15% speed difference be significant to you?
2) have you found an easy way to connect to your database in both languages? I found getting the JDBC connection for firebird to work a bit tricky (probably lack of experience on my part). How would you connect to it via C++?
3) how scalable does the result have to be? Are you looking at something that needs to be able to deal with spikes in activity, or will it be steady growth?
1) will that 15% speed difference be significant to you?
2) have you found an easy way to connect to your database in both languages? I found getting the JDBC connection for firebird to work a bit tricky (probably lack of experience on my part). How would you connect to it via C++?
3) how scalable does the result have to be? Are you looking at something that needs to be able to deal with spikes in activity, or will it be steady growth?
#3
Posted 05 October 2009 - 03:37 AM
For the requirements you posted, C++ is a definite "no go".
1. Performance: C++ can outperform Java on server (by a slight margin) only if you are an extremely experienced programmer ready to dive into dirty hacks with implementing your own memory allocators and/or heavy using C++ templates and inline code in headers. But performance lies almost always in used algorithms - you will write your Java version 2-3 times faster and have much more time for fine tuning the algorithms, thus getting much higher performance from the Java version than from the C++.
2. Memory leaks. Even a slight memory leak will kill a long running server side application. And memory management in C++ is a great PITA.
3. Database access - Java is a clear win here. Anything like Hibernate/iBatis for C++? I doubt it - it is impossible to implement such a solution in C++. Database access is much easier with Java, there are lots of libraries for that and you can easily make it cross-platform.
4. Network security - C++'s inherent lack of security control disqualifies this language for your task. Most of the bugs causing security vulnerabilities are not possible in Java.
5. No-one uses C++ for NEW projects now, except in game industry.
1. Performance: C++ can outperform Java on server (by a slight margin) only if you are an extremely experienced programmer ready to dive into dirty hacks with implementing your own memory allocators and/or heavy using C++ templates and inline code in headers. But performance lies almost always in used algorithms - you will write your Java version 2-3 times faster and have much more time for fine tuning the algorithms, thus getting much higher performance from the Java version than from the C++.
2. Memory leaks. Even a slight memory leak will kill a long running server side application. And memory management in C++ is a great PITA.
3. Database access - Java is a clear win here. Anything like Hibernate/iBatis for C++? I doubt it - it is impossible to implement such a solution in C++. Database access is much easier with Java, there are lots of libraries for that and you can easily make it cross-platform.
4. Network security - C++'s inherent lack of security control disqualifies this language for your task. Most of the bugs causing security vulnerabilities are not possible in Java.
5. No-one uses C++ for NEW projects now, except in game industry.
#4
Posted 05 October 2009 - 04:06 AM
1. Wrong. Java doesn't have access to the new methods for mass socket handling, such as /dev/epoll and Solaris's IOCP sockets, which are often far, far faster than select() or /dev/poll based methods. (Hello Java) However, this gain is usually only visible once you're around ~10000 connections.
2. Not really. There are dozens of excellent profiling tools for C and C++ that help eliminate memory leaks, not to mention with C++ you also have smart pointers and the ability to add reference counting anywhere you need it.
3. Database access is a bit complex for someone entering the language, but it isn't hard. You'll always have a C library for any database you choose. And absolutely nothing is impossible in C++ or C.
4. lol.
5. lol.
2. Not really. There are dozens of excellent profiling tools for C and C++ that help eliminate memory leaks, not to mention with C++ you also have smart pointers and the ability to add reference counting anywhere you need it.
3. Database access is a bit complex for someone entering the language, but it isn't hard. You'll always have a C library for any database you choose. And absolutely nothing is impossible in C++ or C.
4. lol.
5. lol.
#5
Posted 05 October 2009 - 04:29 AM
1. Wrong, Java already can use epoll (see: Enhancements in Java I/O). And as you said, the difference is negligible (you really do not want to have 10000 connections anyway). And code C++ has no possibility to inline calls to dynamically loaded modules or perform lock-ellision optimizations. This is often much higher performance penalty in server environments.
2. Those excellent tools usually cannot be run in production because they cause 100x slowdown (like Valgrind). But even if you can repeat the leak in test environment, you still have to profile and search these bugs. There are scientific studies showing that fixing these bugs cost about 3-6 times more than fixing typical bugs in Java: http://www.lanl.gov/...aEfficiency.pdf
And smart pointers - lol. They are a real performance killer. Good for managing rarely-used resources, but not memory.
3. Please give me a good ORM tool for C++. Not found? What a pity.
Again you are wrong - it is impossible to write a good and easy to use ORM for C++, just as it is impossible to write an efficient GC for C++. There are no annotations and no standard runtime proxy generation in C++, so the only thing you can end up with is some kind of static ugly XML-based code generation tool, which is far from the productivity offered by e.g. Hibernate.
2. Those excellent tools usually cannot be run in production because they cause 100x slowdown (like Valgrind). But even if you can repeat the leak in test environment, you still have to profile and search these bugs. There are scientific studies showing that fixing these bugs cost about 3-6 times more than fixing typical bugs in Java: http://www.lanl.gov/...aEfficiency.pdf
And smart pointers - lol. They are a real performance killer. Good for managing rarely-used resources, but not memory.
3. Please give me a good ORM tool for C++. Not found? What a pity.
Again you are wrong - it is impossible to write a good and easy to use ORM for C++, just as it is impossible to write an efficient GC for C++. There are no annotations and no standard runtime proxy generation in C++, so the only thing you can end up with is some kind of static ugly XML-based code generation tool, which is far from the productivity offered by e.g. Hibernate.
#6
Posted 05 October 2009 - 04:39 AM
@JCoder: Your last statement reveals the flaws in your first four. The game industry cannot afford to have memory leaks, or games crash. The game industry cannot afford to have inefficient networking, or MMO's lag. The game industry cannot afford poor security, or people cheat. The game industry uses databases heavily in servers.
Java makes it easier to not do something stupid, it was designed for that. However, there is a cost to that. Java uses it's own methods for connecting to databases, for example, that may not be as feature-rich as those provided by the database manufacturer. Java will ALWAYS force Garbage Collection on you, even if you can't afford it. I'm not saying C++ is perfect, but your arguments don't carry the smell of fact about them.
Java makes it easier to not do something stupid, it was designed for that. However, there is a cost to that. Java uses it's own methods for connecting to databases, for example, that may not be as feature-rich as those provided by the database manufacturer. Java will ALWAYS force Garbage Collection on you, even if you can't afford it. I'm not saying C++ is perfect, but your arguments don't carry the smell of fact about them.
#7
Posted 05 October 2009 - 04:52 AM
#8
Posted 05 October 2009 - 04:52 AM
Quote
The game industry cannot afford to have memory leaks, or games crash. The game industry cannot afford to have inefficient networking, or MMO's lag. The game industry cannot afford poor security, or people cheat. The game industry uses databases heavily in servers.
Of course it can! Memory leaks are not a problem - games are usually designed so that memory allocation occurs only at loading new levels, but not during gameplay. And even a slight memory leak does not lead to a crash - how long do you play a game - several hours? And the server system has to run for several months without a restart. So a huge difference here. A crash once a 3 days of continuous runtime is not a problem for a desktop application, but a huge problem for a server one.
C++ is mainly used because of large amount of gaming libraries and good performance it can deliver to most demanding productions. Sometimes that 15% of performance gain IS worth fighting with a poorly-designed language. But this is a niche.
Quote
The game industry uses databases heavily in servers.
Quote
Java will ALWAYS force Garbage Collection on you, even if you can't afford it.
Wrong. No allocations - no garbage collection. Besides, GC is much cheaper than naive manual memory management.
#9
Posted 05 October 2009 - 04:59 AM
If memory leaks are not a problem (and they are), why did you use it as an argument?
Ah right right...so that ~400Mb map gets loaded at once instead of allocated once a region is within visible range. Oh...wait, no.
Really? I can't think of any MMORPG that uses Java for its server - mind providing two or three examples?
"Poorly-designed language" is an opinion - not a fact.
And YES, java does garbage collection even if there have been no explicit allocations, because those java routines you're using do, guess what, allocations on their own.
And the doorcrasher - guess what the majority of Java's VM's are written in? C++.
Ah right right...so that ~400Mb map gets loaded at once instead of allocated once a region is within visible range. Oh...wait, no.
Really? I can't think of any MMORPG that uses Java for its server - mind providing two or three examples?
"Poorly-designed language" is an opinion - not a fact.
And YES, java does garbage collection even if there have been no explicit allocations, because those java routines you're using do, guess what, allocations on their own.
And the doorcrasher - guess what the majority of Java's VM's are written in? C++.
#10
Posted 05 October 2009 - 05:01 AM
1. JNI. And you can get to the lowest layers you can with C or C++.
2. What idiot would use a profiling tool in production? They are for testing, not production builds.
And what if the bug is occuring ONLY on production server? Profiling production systems in Java can be done, without affecting stability and/or performance.
3.
You just proved me I was right - LiteSQL: alpha quality XML-based code generation stuff, not ready for production, and nowhere near the usefullness of JPA / Hibernate. SOCI and DTL are not true ORMs, but only low level query helpers.
2. What idiot would use a profiling tool in production? They are for testing, not production builds.
And what if the bug is occuring ONLY on production server? Profiling production systems in Java can be done, without affecting stability and/or performance.
3.
Quote
You just proved me I was right - LiteSQL: alpha quality XML-based code generation stuff, not ready for production, and nowhere near the usefullness of JPA / Hibernate. SOCI and DTL are not true ORMs, but only low level query helpers.
#11
Posted 05 October 2009 - 05:18 AM
TkTech said:
If memory leaks are not a problem (and they are), why did you use it as an argument?
Ah right right...so that ~400Mb map gets loaded at once instead of allocated once a region is within visible range. Oh...wait, no.
Ah right right...so that ~400Mb map gets loaded at once instead of allocated once a region is within visible range. Oh...wait, no.
It seems you can't read with understanding. For a short-lived application a memory leak of 1 MB per hour is not a problem. If one user encounters random crash once per 3 days it is also not a problem. But for a server-side application it is a disaster costing lots of money.
Quote
Really? I can't think of any MMORPG that uses Java for its server - mind providing two or three examples?
The Witcher: VERSUS! - Multiplayer Browser Game
RuneScape - the massive online adventure game by Jagex Games Studio
Puzzle Pirates
Runescape has higher market share than EverQuest II or Second Life.
Quote
"Poorly-designed language" is an opinion - not a fact.
Maybe. But an opinion well supported by facts. See C++ Frequently Questioned Answers
Quote
And YES, java does garbage collection even if there have been no explicit allocations, because those java routines you're using do, guess what, allocations on their own.
So what? Even if they use some temporary objects, they are mostly allocated on stack, and if not, they finish their lives in the eden generation, which is almost as cheap as stack allocation.
Quote
And the doorcrasher - guess what the majority of Java's VM's are written in?
This does not prove anything. They had to choose some low-level language. Many JVMs use pure C, not C++.
Ok, I made some quick perfornance test that should mimic the typical behaviour of server-based applications. I know this is a microbenchmark, and you SHOULD NOT draw general conclusions from this, but it shows that "Java vs C++ performance" thing cannot be summarized by simply saying "Java is 15% slower".
A typical task for server-side applications is generating pages - usually dynamic pages. If the component framework is clever, this usually boils down to concatenating lots of strings, most of which are already somewhere cached. The code for the benchmark is as follows:
C++ version:
#include <string>
#include <wchar.h>
using namespace std;
const int STRINGS_COUNT = 10000;
const int LOOPS_COUNT = 10000;
wstring test() {
wstring x = L"";
const wstring y = L"aaaaaaaaaa";
for (int i = 0; i < STRINGS_COUNT; i++)
x += y;
return x;
}
int main() {
for (int i = 0; i < LOOPS_COUNT; i++)
test();
return 0;
}
Java version:
import java.util.*;
import java.lang.*;
public class Test2 {
private static final int STRINGS_COUNT = 10000;
private static final int LOOPS_COUNT = 10000;
private static String test() {
StringBuilder x = new StringBuilder();
for (int i = 0; i < STRINGS_COUNT; i++)
x.append("aaaaaaaaaa");
return x.toString();
}
public static void main(String[] args) {
for (int i = 0; i < LOOPS_COUNT; i++)
test();
}
}
Compiler versions:
pkolaczk@darkstar:~$ gcc --version gcc (GCC) 4.2.4 Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. pkolaczk@darkstar:~$ java -version java version "1.6.0_16" Java(TM) SE Runtime Environment (build 1.6.0_16-b01) Java HotSpot(TM) Client VM (build 14.2-b01, mixed mode, sharing)
Results:
pkolaczk@darkstar:~$ g++ -O2 -fomit-frame-pointer test2.cpp pkolaczk@darkstar:~$ time a.out real 0m14.240s user 0m9.245s sys 0m2.866s pkolaczk@darkstar:~$ time a.out real 0m13.779s user 0m9.208s sys 0m2.755s pkolaczk@darkstar:~$ time a.out real 0m13.894s user 0m9.366s sys 0m2.874s pkolaczk@darkstar:~$ time java -server -Xms32M -Xmx32M Test2 real 0m12.436s user 0m10.309s sys 0m0.193s pkolaczk@darkstar:~$ time java -server -XX:NewRatio=2 -Xms64M -Xmx64M Test2 real 0m12.046s user 0m9.432s sys 0m0.132s pkolaczk@darkstar:~$ time java -server -XX:NewRatio=2 -Xms64M -Xmx64M Test2 real 0m11.461s user 0m9.420s sys 0m0.142s pkolaczk@darkstar:~$ time java -server -XX:NewRatio=2 -Xms64M -Xmx64M Test2 real 0m11.387s user 0m9.442s sys 0m0.102s pkolaczk@darkstar:~$ time java -server -XX:NewRatio=2 -Xms16M -Xmx16M Test2 real 0m12.127s user 0m9.929s sys 0m0.164s pkolaczk@darkstar:~$ time java -server -XX:NewRatio=2 -Xms16M -Xmx16M Test2 real 0m12.049s user 0m10.030s sys 0m0.174s pkolaczk@darkstar:~$ time java -server -XX:NewRatio=2 -Xms5M -Xmx5M Test2 real 0m13.625s user 0m11.350s sys 0m0.263s pkolaczk@darkstar:~$ time java -server -XX:NewRatio=2 -Xms5M -Xmx5M Test2 real 0m14.064s user 0m11.591s sys 0m0.281s
This is mostly memory-bound benchmark, and as you can see, you can get quite huge performance benefit when adding more memory to JVM, and GC outperforms manual allocation even in this simplictic test. C++ applications with manual memory management have no such possibility (ok, you can manually code your own fine-tuned allocator - good luck if you get it better than STL's built-in allocators).
Note that this test favours C++ in such a way, that it reallocates memory in a way not to cause fragmentation - and memory reference locality is very good.
In a real world, large, long-running multithreaded C++ application heap can get quite fragmented which can deteriorate performance further. This does not happen in Java.
Edited by TkTech, 07 October 2009 - 01:06 AM.
#12
Posted 09 October 2009 - 06:45 PM
Quote
Runescape has higher market share than EverQuest II or Second Life.


Sign In
Create Account


Back to top









