C# 如何提高使用多线程创建大量对象的应用程序的性能?
我正在为NoSQL数据库编写一个C#SDK,为了处理请求(序列化或非序列化、签名),我必须创建很多(小)对象 我在一个简单的程序中测试了这个新SDK的性能,该程序创建了指定数量的线程,并在每个线程中循环调用API作为playload。使用1 thead时,QPS达到6K+,但随着线程数的增加,总体QPS减少而不是增加 为了找出原因,我简化了我的测试程序,并将负载减少为一个非常简单的代码,而不是实际调用我的SDK接口:C# 如何提高使用多线程创建大量对象的应用程序的性能?,c#,multithreading,performance,C#,Multithreading,Performance,我正在为NoSQL数据库编写一个C#SDK,为了处理请求(序列化或非序列化、签名),我必须创建很多(小)对象 我在一个简单的程序中测试了这个新SDK的性能,该程序创建了指定数量的线程,并在每个线程中循环调用API作为playload。使用1 thead时,QPS达到6K+,但随着线程数的增加,总体QPS减少而不是增加 为了找出原因,我简化了我的测试程序,并将负载减少为一个非常简单的代码,而不是实际调用我的SDK接口: for (int i = 0; i < 100000; i ++) {
for (int i = 0; i < 100000; i ++) {
double a = Math.Pow(3.14, 0.5);
}
for(int i=0;i<100000;i++){
双a=数学功率(3.14,0.5);
}
性能结果相当不错:
1线程132 QPS2线程261 QPS
4线程1028 QPS
8线程1826 QPS 但当我将有效载荷更改为:
for (int i = 0; i < 100000; i ++) {
var c = new string('X', 50);
}
for(int i=0;i<100000;i++){
var c=新字符串('X',50);
}
性能如下所示:
1线程300 QPS2线程497 QPS
4线程596 QPS
8线程518 QPS 如果我在有效载荷中创建一些其他对象,结果将是相同的(不是线性的) (上述两种情况均未达到CPU和内存限制) 为什么??我的SDK会自然而然地创建一个对象,那么有办法解决吗 我的一些猜测:
多线程编程的主要规则是,创建的线程不应超过
CPU内核+1
。这是因为您创建了许多线程,它们都试图同时完成工作,而您的CPU和操作系统通过上下文切换降低了性能。这是一个非常耗时的操作——在同一个线程中执行两件工作比在两个线程中执行一件工作要好
例如,有很多技术可以提高应用程序的性能,但您应该自己研究,因为这是一个非常广泛的主题。线程并不便宜。您是如何创建这些新线程的?你在利用异步IO吗?@Tejas在这两个案例中,我没有做任何涉及异步的事情。在主线程中,我创建了1-8个线程来循环调用我的SDK接口并等待它们完成。一般来说,如果您要进行持续的高分配,您将研究对象池和重用之类的工具-明智地、适当地完成(不太过分),你可以削减大量的分配和收集,但你不想走得太远,因为这样做也会人为地分割内存空间。但可以肯定的是:分配不是免费的,即使是免费的cheap@MarcGravell我知道分配不是免费的,但在多线程场景中它们会变得更昂贵吗?我这里的问题是如何使性能以线程的方式线性增加。@Haowei在您实际分析之前,这是一个猜测游戏;是的,如果需要,分配可能是个问题。正如我所提到的,共享是另一个大方法。你提到protobuf,我觉得很有趣,因为这也是我涉足的一个领域——protobuf net在内部为工作缓冲区之类的东西维护微池。嗯,我的计算机有24个CPU内核,我最多只启动8个线程。所以这不是我的情况。