C ++ vs. Java Looping on Strings performance comparison

I did some performance tests with C ++ (implemented in Visual Studio Community Edition 2015) and Java (1.7) for loops.
Below is the source code:

Java:

long startTime = 0;
long endTime = 0;
long totalTime = 0;

startTime = System.currentTimeMillis();
for (long counter = 0; counter < numberOfIterations; counter++)
{
    System.out.println("01234");
}
endTime = System.currentTimeMillis();
totalTime = endTime - startTime;

      

C ++ (Windows based, x64 version optimized for speed):

ULONGLONG startTime = 0;
ULONGLONG endTime = 0;
ULONGLONG elapsedTime = 0;

startTime = GetTickCount64();
for (LONGLONG counter = 0; counter < numberOfIterations; counter++)
{
    cout << "01234" << endl;
}
endTime = GetTickCount64();
elapsedTime = endTime - startTime;

      

The results really surprised me when I spin / loop them 100,000 times. Here they are:
Java:

  • 1st attempt: 31.361 milliseconds
  • Second attempt: 6,316 milliseconds
  • Third attempt: 6.865 milliseconds

C ++:

  • 1st attempt: 40,000 milliseconds
  • Second attempt: 37.703 milliseconds
  • Third attempt: 20,734 milliseconds

Then I had another set of test cases

Java:

long startTime = 0;
long endTime = 0;
long totalTime = 0;
startTime = System.currentTimeMillis();
for(long counter = 0; counter < numberOfIterations; counter++) {
    String tempString = new String("test");
}
endTime = System.currentTimeMillis();

      

C ++ (Windows based, x64 version optimized for speed):

ULONGLONG startTime = 0;
ULONGLONG endTime = 0;
ULONGLONG elapsedTime = 0;

startTime = GetTickCount64();
for (LONGLONG counter = 0; counter < numberOfIterations; counter++)
{
    string tempString = "test";
}
endTime = GetTickCount64();
elapsedTime = endTime - startTime;

      

Again, the results are really more amazing when I rotate / loop them 10,000,000 times. Here they are: Java

  • First attempt: 7 milliseconds
  • Second attempt: 7 milliseconds
  • Third attempt: 7 milliseconds

C ++:

  • First attempt: 125 milliseconds
  • Second attempt: 125 milliseconds
  • Third attempt: 125 milliseconds

But on empty C ++ loops.

Before doing this test, I really thought that C ++ would always execute Java at a low level or on a specific OS / platform. But, in this case, does that mean Java has a more efficient way of handling strings specifically if it's already in volumes?



Thanks to

+3


source to share


1 answer


Finally, I was able to take the time to post an answer here as I promised. But my apologies for that. Anyway, here are the statistics I have collected. Please bear with me, this is a rather long answer. By the way, both of them were performed on Windows 10 Pro x64 Machine =)!




First code (both C ++ and Java): In Java on Windows:

public void testForLoopCreateInt(long numberOfIterations) {
    ArrayList<Integer> listOfIntegers = new ArrayList<Integer>();
    long startTime = 0;
    long endTime = 0;
    long totalTime = 0;
    System.out.println("\n===========================" + "\ntestForLoopCreateInt() Looping for: " + numberOfIterations);
    startTime = System.currentTimeMillis();
    for(long counter = 0; counter < numberOfIterations; counter++) {
        int i = 0;
        listOfIntegers.add(i);
    }
    endTime = System.currentTimeMillis();
    totalTime = endTime - startTime;
    System.out.println("Total time: " + totalTime + " milliseconds");

    System.out.println("===========================testForLoopCreateInt()");

    for (int indexer = 0; indexer < 10; indexer++) {
        int y = listOfIntegers.get(indexer);
    }
}

      

In C ++, over some Win32 API:

void Loops::testForLoopCreateInt(LONGLONG numberOfIterations)
{
    cout << "\n===========================" << "\ntestForLoopCreateInt() Looping for: " << numberOfIterations << endl;
    vector<int> vectorOfInts;

    high_resolution_clock::time_point startTime = high_resolution_clock::now();
    for (LONGLONG counter = 0; counter < numberOfIterations; counter++)
    {
        int i = 0;
        vectorOfInts.push_back(i);
    }
    high_resolution_clock::time_point endTime = high_resolution_clock::now();

    duration<double, std::milli> totalTime = endTime - startTime;
    cout << "Total time: " << totalTime.count() << " milliseconds" << endl;
    cout << "===========================testForLoopCreateInt()" << endl;

    for (int indexer = 0; indexer < 10; indexer++) {
        int y = vectorOfInts.at(indexer);
    }
}

      

When they each had the number of iterations set to some value, the following results:

Java:

  • 10 Iterations: 0.00ms
  • 100 Iterations: 0.00ms
  • 1000 Iterations: 0.00ms
  • 10000 Iterations: 1.00ms
  • 100000 Iterations: 4.00 ms
  • 1,000,000 Iterations: 12.00 ms
  • 10,000,000 Iterations: 106.00 ms
  • 100,000,000 Iterations: 1,747.00 ms

C ++:

  • 10 Iterations: 0.001803 ms
  • 100 Iterations: 0.00601 ms
  • 1000 Iterations: 0.013521 ms
  • 10000 Iterations: 0.067005 ms
  • 100000 Iterations: 0.506291 ms
  • 1,000,000 Iterations: 4.4806 ms
  • 10000000 Iterations: 61.1632 ms
  • 100,000,000 Iterations: 679.341 ms



Second code (both C ++ and Java): In Java on Windows:

public void testForLoopCreateUniformStringAndStoreToArrayList(long numberOfIterations) {
    ArrayList<String> listOfIntegers = new ArrayList<String>();
    long startTime = 0;
    long endTime = 0;
    long totalTime = 0;
    System.out.println("\n===========================" + "\ntestForLoopCreateUniformStringAndStoreToArrayList() Looping for: " + numberOfIterations);
    startTime = System.currentTimeMillis();
    for(long counter = 0; counter < numberOfIterations; counter++) {
        String string = new String("01234");
        listOfIntegers.add(string);
    }
    endTime = System.currentTimeMillis();
    totalTime = endTime - startTime;
    System.out.println("Total time: " + totalTime + " milliseconds");

    System.out.println("===========================testForLoopCreateUniformStringAndStoreToArrayList()");

    for (int indexer = 0; indexer < 10; indexer++) {
        String y = listOfIntegers.get(indexer);
    }
}

      

In C ++, over some Win32 APIs:

void Loops::testForLoopCreateUniformStringAndStoreToVector(LONGLONG numberOfIterations)
{
    cout << "\n===========================" << "\ntestForLoopCreateUniformStringAndStoreToVector() Looping for: " << numberOfIterations << endl;
    vector<string> vectorOfStrings;

    high_resolution_clock::time_point startTime = high_resolution_clock::now();
    for (LONGLONG counter = 0; counter < numberOfIterations; counter++)
    {
        string str000("01234");
        vectorOfStrings.push_back(str000);
    }
    high_resolution_clock::time_point endTime = high_resolution_clock::now();

    duration<double, std::milli> totalTime = endTime - startTime;
    cout << "Total time: " << totalTime.count() << " milliseconds" << endl;
    cout << "===========================testForLoopCreateUniformStringAndStoreToVector()" << endl;

    for (int indexer = 0; indexer < 10; indexer++) {
        string y = vectorOfStrings.at(indexer);
    }
}

      

When they each had the number of iterations set to some value, the following results:

Java:

  • 10 Iterations: 0.00ms
  • 100 Iterations: 0.00ms
  • 1000 Iterations: 1.00 ms
  • 10000 Iterations: 1.00ms
  • 100,000 Iterations: 6.00 ms
  • 1,000,000 Iterations: 24.00 ms
  • 10000000 Iterations: 2,742.00 ms
  • 100,000,000 Iterations: 33,371.00 ms

C ++:

  • 10 Iterations: 0.003605 ms
  • 100 Iterations: 0.018329 ms
  • 1000 Iterations: 0.064301 ms
  • 10000 Iterations: 0.71722 ms
  • 100000 Iterations: 13.9406 ms
  • 1,000,000 Iterations: 88.5781 ms
  • 10000000 Iterations: 931.526 ms
  • 100,000,000 Iterations: 10,768.9 ms

So these are the results, I'm not sure if this is biased or not, but I make it as fair as I can, in both C ++ (on windows) and Java (on windows). Thus, you will be the judge.

Thank.

+2


source







All Articles