Java线程创建性能与C#线程创建性能对比C ++(本机线程)?

时间:2013-10-09 10:55:01

标签: c# java c++ multithreading performance

我很有趣在Java,C#和C ++中创建线程的实际成本是多少?我知道当线程创建时必须完成一堆操作:分配线程堆栈,初始化描述符等。

但我对实际成本很感兴趣。 C#和Java使用不同的VM和不同的JIT,C ++执行本机代码。因此,所有这些语言中的线程创建时间都不同。我还听说Java中的线程创建比C#慢得多。有人可以就这个问题提供有用的答案和解释吗?

3 个答案:

答案 0 :(得分:7)

在C#,Java和Visual C ++中创建10,000个线程的基准:

C#

class Program
{
    static void Main(string[] args)
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        for (int i = 0; i < 10000; i++)
        {
            Thread thread = new Thread(DoNothing);
            thread.Start();
        }
        watch.Stop();
        Console.WriteLine(watch.Elapsed);
    }

    static void DoNothing()
    {
        //Do Nothing
    }
}

结果:1​​.7638042秒

爪哇

public class ThreadBencher {

    public static void main(String[] args) {
        Runnable r = new Runnable() {
             public void run() {
                 //Do nothing
             }
         };

         long startTime = System.nanoTime();
         for (int i = 0; i < 10000; i++) {
             Thread thread = new Thread(r);
             thread.start();
         }
         long stopTime = System.nanoTime();
         long totalTime = stopTime - startTime;
         System.out.print(totalTime);

    }

}

结果:1​​.514557805秒(或1514557805纳秒)

Visual C ++

DWORD WINAPI DoNothing( LPVOID lpParam ) 
{
    return 0;
}

void main()
{
    HANDLE ourThreadHandle = 0;
    SYSTEMTIME st1;
    SYSTEMTIME st2;
    int i;
    GetLocalTime(&st1);
    for (i = 0; i < 10000; i++) {
        ourThreadHandle = CreateThread( NULL, 0, DoNothing, 0, 0, NULL);
    }
    GetLocalTime(&st2);
    double dblSt1 = st1.wSecond + (st1.wMilliseconds / 1000);
    double dblSt2 = st2.wSecond + (st2.wMilliseconds / 1000);
    double result = dblSt2 - dblSt1;
    cout << st1.wSecond << "." << st1.wMilliseconds << endl;
    cout << st2.wSecond << "." << st2.wMilliseconds << endl;
}

结果(从输出手动计算后):0.925秒

(免责声明:我不太了解C ++,所以C ++代码很好地拼凑在一起)

注意:这是在64位Windows 8环境中完成的。

答案 1 :(得分:5)

创建线程时会发生这种情况。

创建新线程时,它会共享其代码部分,数据部分和操作系统资源,例如与其他线程一起打开文件。但是它被分配了自己的堆栈,寄存器集和程序计数器。

线程费用

线程在内存使用和性能方面对您的程序(和系统)造成了实际成本。每个线程都需要在内核内存空间和程序的内存空间中分配内存。

管理线程和协调其调度所需的核心结构使用有线内存存储在内核中。您的线程的堆栈空间和每线程数据存储在程序的内存空间中。

  

首先创建并初始化大多数这些结构   创建线程 - 一个可能相对昂贵的过程,因为   与内核进行必要的交互。

其中一些成本是可配置的,例如为辅助线程分配的堆栈空间量。创建线程的时间成本是粗略的近似值,应该仅用于相互比较。根据处理器负载,计算机速度以及可用系统和程序存储器的数量,线程创建时间可能会有很大差异。

enter image description here

  

线程不消耗内存(除了堆栈,它是   恒定大小);进程消耗内存。线程的全部要点   是他们分享过程状态。

公共语言运行时(CLR)线程的堆栈空间设置为 (由CLR提供)默认情况下为1MB(64位代码线程为4MB)。

在C ++中,它为堆栈保留1MB(它映射其地址空间),但它不一定分配在物理内存中,只是它的一小部分。如果堆栈增长超过生成页面错误并分配更多物理内存。

Java线程创建很昂贵,因为涉及到相当多的工作:

  • 必须为线程堆栈分配和初始化大块内存。

  • 需要进行系统调用以使用主机操作系统创建/注册本机线程。

  • 需要创建,初始化描述符并将其添加到JVM内部数据结构中。

从某种意义上来说它也是昂贵的,只要它存在,线程就会占用资源;例如线程堆栈,从堆栈可以访问的任何对象,JVM线程描述符,OS本机线程描述符。

答案 2 :(得分:0)

C ++通常是一种更快的语言,尽管它可能是一种难学的语言;因此,了解更多基本功能需要更长时间,这可能会减慢您在制作应用程序时对其进行编码的过程