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

Mai*_*r00 8 c# c++ java performance multithreading

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

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

All*_*ice 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
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:1.7638042秒

Java的

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

    }

}
Run Code Online (Sandbox Code Playgroud)

结果: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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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


Dil*_*eep 5

这就是创建线程时发生的情况.

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

线程成本

在内存使用和性能方面,线程对程序(和系统)来说是一个真正的成本.每个线程都需要在内核内存空间和程序的内存空间中分配内存.

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

大多数这些结构都是在您第一次创建线程时创建和初始化的 - 由于与内核的所需交互,该过程可能相对昂贵.

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

在此输入图像描述

线程不消耗内存(除了堆栈,它是恒定大小的); 进程消耗内存.线程的全部意义在于它们共享进程状态.

公共语言运行时(CLR)线程的堆栈空间默认设置为(由CLR配置)1MB(64位代码线程为4MB).

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

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

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

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

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

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