【问题标题】:C++ and Java's Looping on Strings performance comparisonsC++ 和 Java 的字符串循环性能比较
【发布时间】:2017-07-05 11:29:33
【问题描述】:

我针对 C++(在 Visual Studio Community Edition 2015 中实现)和 Java (1.7) for 循环进行了一些性能测试。
以下是源代码:

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,发布版本 x64,针对速度进行了优化):

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;

当我将它们旋转/循环 100,000 次时,结果真的让我感到惊讶。 他们来了:
Java:

  • 第一次尝试:31,361 毫秒
  • 第二次尝试:6,316 毫秒
  • 第三次尝试:6,865 毫秒

C++:

  • 第一次尝试:40,000 毫秒
  • 第二次尝试:37,703 毫秒
  • 第三次尝试:20,734 毫秒

然后我又有了一组测试用例

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,发布版本 x64,针对速度进行了优化):

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;

再次,当我将它们旋转/循环 10,000,000 次时,结果确实更令人惊讶。 他们来了: Java

  • 第一次尝试:7 毫秒
  • 第二次尝试:7 毫秒
  • 第三次尝试:7 毫秒

C++:

  • 第一次尝试:125 毫秒
  • 第二次尝试:125 毫秒
  • 第三次尝试:125 毫秒

但是在 C++ 的空循环上。

在进行此测试之前,我实际上认为 C++ 在低级别或特定于操作系统/平台的实现中将始终胜过 Java。 但是,在这种情况下,这是否意味着 Java 有更有效的方式来处理字符串,特别是如果它已经在卷中?



谢谢

【问题讨论】:

  • 这里的问题:您的示例可能太天真了,无法得出有意义的数字。例如,请参阅stackoverflow.com/questions/504103/…。我的意思是:Java JIT 做了很多优化。它可能很快 认为创建刚刚被丢弃的字符串对象是没有意义的。而对于另一个测试用例:你明白当打印到控制台时(?)大部分时间无论如何都会花在系统调用上?
  • 能否请您在第一个 c++ 示例中的循环前添加两行:ios_base::sync_with_stdio(false);cin.tie(NULL);,然后再试一次?
  • endl 更改为'\n'
  • @PeteBecker: 不,endl 是正确的,因为System.out.println 也会刷新缓冲区。公平地说,两种语言都应该刷新或不刷新。

标签: java c++ visual-c++


【解决方案1】:

最后,我能够按照我的承诺抽出时间在这里发布答案。但我为此道歉。无论如何,这是我收集的统计数据。请耐心等待,这是一个很长的答案。顺便说一句,它们都是在 Windows 10 Pro x64 Machine 中执行的 =)!


第一个代码(C++ 和 Java): 在 Windows 上的 Java 中:

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);
    }
}

在 C++ 中通过一些 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);
    }
}

当每一个都将迭代次数设置为某个值时,结果如下:

Java:

  • 10 次迭代:0.00 毫秒
  • 100 次迭代:0.00 毫秒
  • 1000 次迭代:0.00 毫秒
  • 10000 次迭代:1.00 毫秒
  • 100000 次迭代:4.00 毫秒
  • 1000000 次迭代:12.00 毫秒
  • 10000000 次迭代:106.00 毫秒
  • 100000000 次迭代:1,747.00 毫秒

C++:

  • 10 次迭代:0.001803 毫秒
  • 100 次迭代:0.00601 毫秒
  • 1000 次迭代:0.013521 毫秒
  • 10000 次迭代:0.067005 毫秒
  • 100000 次迭代:0.506291 毫秒
  • 1000000 次迭代:4.4806 毫秒
  • 10000000 次迭代:61.1632 毫秒
  • 100000000 次迭代:679.341 毫秒

第二个代码(C++ 和 Java): 在 Windows 上的 Java 中:

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);
    }
}

在 C++ 中通过一些 Win32 API:

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);
    }
}

当每一个都将迭代次数设置为某个值时,结果如下:

Java:

  • 10 次迭代:0.00 毫秒
  • 100 次迭代:0.00 毫秒
  • 1000 次迭代:1.00 毫秒
  • 10000 次迭代:1.00 毫秒
  • 100000 次迭代:6.00 毫秒
  • 1000000 次迭代:24.00 毫秒
  • 10000000 次迭代:2,742.00 毫秒
  • 100000000 次迭代:33,371.00 毫秒

C++:

  • 10 次迭代:0.003605 毫秒
  • 100 次迭代:0.018329 毫秒
  • 1000 次迭代:0.064301 毫秒
  • 10000 次迭代:0.71722 毫秒
  • 100000 次迭代:13.9406 毫秒
  • 1000000 次迭代:88.5781 毫秒
  • 10000000 次迭代:931.526 毫秒
  • 100000000 次迭代:10,768.9 毫秒

所以这些是结果,我不确定这是否有偏见,但我尽可能公平地对待 C++(在 Windows 上)和 Java(在 Windows 上)。所以你会是法官。

谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 2016-04-27
    • 2017-08-13
    相关资源
    最近更新 更多