Jump to content

Comparison of Java and C++ for server-based application

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
38 replies to this topic

#1
penkomitev

penkomitev

    Learning Programmer

  • Members
  • PipPipPip
  • 31 posts
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
You can visit something interesting HERE

#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
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?
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
JCoder

JCoder

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 245 posts
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.

#4
TkTech

TkTech

    The Crazy One

  • Moderators
  • 1,396 posts
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.

#5
JCoder

JCoder

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 245 posts
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.

#6
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
@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.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#7
TkTech

TkTech

    The Crazy One

  • Moderators
  • 1,396 posts
1. Ah, you've proved me wrong there. I wasn't aware Java had finally added support. Now what about Solaris & Windows IO completion ports? FreeBSD's kquene, ect...

2. What idiot would use a profiling tool in production? They are for testing, not production builds.

3. LiteSQL, SOCI, DTL

#8
JCoder

JCoder

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 245 posts

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.
Ok, I meant - PC/console game industry. Server side game industry uses Java with a great success. Especially MMOG segment.

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
TkTech

TkTech

    The Crazy One

  • Moderators
  • 1,396 posts
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++.

#10
JCoder

JCoder

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 245 posts
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.

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
JCoder

JCoder

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 245 posts

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.

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
Aereshaa

Aereshaa

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 790 posts

Quote

Runescape has higher market share than EverQuest II or Second Life.
WTFLOL!!! My bull**** meter just spun.
Watches: Nanoha, Haruhi, AzuDai. Listens to: E-Type, Dj Melodie, Nightcore.
"When people are wrong they need to be corrected. And then when they can't accept it, an argument ensues." - MeTh0Dz