C# 为什么多线程比单线程慢?
我知道有几个人问了一个类似的问题,但我找不到任何能让我理解为什么速度较慢的回答 因此,我制作了一个小控制台程序,以便于我自己理解VisualStudio2013中的线程对象。我的CPU是一个Intel Core i7,可以使用多线程 我的代码:C# 为什么多线程比单线程慢?,c#,multithreading,C#,Multithreading,我知道有几个人问了一个类似的问题,但我找不到任何能让我理解为什么速度较慢的回答 因此,我制作了一个小控制台程序,以便于我自己理解VisualStudio2013中的线程对象。我的CPU是一个Intel Core i7,可以使用多线程 我的代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Syste
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static TimeSpan MTTime;
static TimeSpan STTime;
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Console.WriteLine(Environment.NewLine + "---------------Multi Process-------------" + Environment.NewLine);
Thread th1 = new Thread(new ParameterizedThreadStart(Process));
Thread th2 = new Thread(new ParameterizedThreadStart(Process));
Thread th3 = new Thread(new ParameterizedThreadStart(Process));
Thread th4 = new Thread(new ParameterizedThreadStart(Process));
th1.Start("A");
th2.Start("B");
th3.Start("C");
th4.Start("D");
th1.Join();
th2.Join();
th3.Join();
th4.Join();
stopwatch.Stop();
MTTime = stopwatch.Elapsed ;
Console.WriteLine(Environment.NewLine + "---------------Single Process-------------" + Environment.NewLine);
stopwatch.Reset();
stopwatch.Start();
Process("A");
Process("B");
Process("C");
Process("D");
stopwatch.Stop();
STTime = stopwatch.Elapsed;
Console.Write(Environment.NewLine + Environment.NewLine + "Multi : "+ MTTime + Environment.NewLine + "Single : " + STTime);
Console.ReadKey();
}
static void Process(object procName)
{
for (int i = 0; i < 100; i++)
{
Console.Write(procName);
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用系统线程;
使用系统诊断;
命名空间控制台应用程序1
{
班级计划
{
静态时间跨度MTTime;
静态时间间隔;
静态void Main(字符串[]参数)
{
秒表秒表=新秒表();
秒表。开始();
Console.WriteLine(Environment.NewLine+“--------------多进程--------------------”+Environment.NewLine);
Thread th1=新线程(新的参数化线程启动(进程));
Thread th2=新线程(新的参数化线程启动(进程));
th3线程=新线程(新参数化的threadstart(进程));
Thread th4=新线程(新的参数化线程启动(进程));
th1.启动(“A”);
th2.启动(“B”);
th3.启动(“C”);
th4.启动(“D”);
th1.Join();
th2.Join();
th3.Join();
th4.Join();
秒表;
MTTime=秒表。已用时间;
Console.WriteLine(Environment.NewLine+“--------------单进程--------------------”+Environment.NewLine);
秒表复位();
秒表。开始();
过程(“A”);
过程(“B”);
过程(“C”);
过程(“D”);
秒表;
STTime=秒表。已用时间;
Console.Write(Environment.NewLine+Environment.NewLine+“Multi:”+MTTime+Environment.NewLine+“Single:”+STTime);
Console.ReadKey();
}
静态无效进程(对象名称)
{
对于(int i=0;i<100;i++)
{
Console.Write(procName);
}
}
}
}
结果图像:
我们可以清楚地看到,多踏板的过程是完全随机的,单个踏板只是一个接一个地进行所有的按压,但我不认为这对速度有影响
起初,我认为我的线程比运行程序所需的进程大,但在换了一个更大的进程后,单线程仍然是最快的。那么,我是否错过了多线程的一个概念?或者说速度较慢是正常的?请注意,
进程
写入控制台(基本上不做其他事情),而控制台的输出(这里作为一种共享资源)速度较慢,需要与其他线程同步
据我所知,您使用的并行化产生了巨大的开销,但没有获得任何加速,因为线程显然一直在等待另一个进程完成对控制台的写入。来自官方文档使用这些流的I/O操作是同步的,这意味着 多个线程可以读取或写入流。这 意味着通常是异步的方法,例如 TextReader.ReadLineAsync,如果对象 表示控制台流 这意味着控制台类处理线程同步,因此,如果线程A和线程B试图写入控制台,控制台将处理它们,一次只能有一个线程能够写入。它背后的处理逻辑是花费更长时间的原因
更新
我建议您再考虑一件事:您正在承受线程创建和连接的开销。此外,通过使用threadpool,您可能会获得轻微的性能升级,请查看以下内容:
好的!感谢阿萨和科多,让我把心思放在正确的地方!我最终制作了一个小的控制台程序,它可以非常清晰地显示每一件事。最后,当使用繁重的处理程序时,多重读取速度要快得多。只要阅读我的代码,你就会轻松理解 结果: 代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
//Timer for speed guidance
static Stopwatch stopwatch;
//Data i use for generate time
static List<int> timeData;
static void Main(string[] args)
{
stopwatch = new Stopwatch();
timeData = new List<int> { 1000, 800, 200, 700, 600, 300, 800, 100, 200, 300, 655, 856, 695, 425 };
////-------------------------- SINGLE THREAD ------------------------------/////
Console.WriteLine("-------------------------------------------------");
Console.WriteLine(" Single Threading Process ");
Console.WriteLine("-------------------------------------------------");
Console.WriteLine(" Process Time Thread ID ");
Console.WriteLine("-------------------------------------------------");
stopwatch.Reset();
stopwatch.Start();
//For each normal that use only 1 thread
foreach(int i in timeData)
{
Process(i);
}
stopwatch.Stop();
//Total time that the program take for making the process happen
Console.WriteLine("*Total : " + stopwatch.Elapsed );
////-------------------------- Mulit Multiple ------------------------------/////
Console.WriteLine("-------------------------------------------------");
Console.WriteLine("-------------------------------------------------");
Console.WriteLine(" Multi Threading Process ");
Console.WriteLine("-------------------------------------------------");
Console.WriteLine(" Process Time Thread ID ");
Console.WriteLine("-------------------------------------------------");
stopwatch.Reset();
stopwatch.Start();
//for each thats use Multiple thread fr the process (can be made with parallel.invoke or Task Library or Thread Library)
Parallel.ForEach(timeData, (i) => Process(i));
//Total time that the program take for making the process happen
Console.WriteLine("*Total : " + stopwatch.Elapsed);
Console.WriteLine("-------------------------------------------------");
Console.ReadKey();
}
// Methode for sumulating long processing
static void Process( int time)
{
stopwatch.Reset();
stopwatch.Start();
//sleep time simulate the IO portion of the process
Thread.Sleep(time);
// The loop simulate de algoritme type of precessing
for (int i = 0; i < time*1000000; i++){}
stopwatch.Stop();
Console.WriteLine( stopwatch.Elapsed + " " + Thread.CurrentThread.ManagedThreadId.ToString());
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用系统线程;
使用系统诊断;
命名空间控制台应用程序1
{
班级计划
{
//速度引导计时器
静态秒表;
//我用于生成时间的数据
静态列表时间数据;
静态void Main(字符串[]参数)
{
秒表=新秒表();
timeData=新列表{1000、800、200、700、600、300、800、100、200、300、655、856、695、425};
////--------------------------单线------------------------------/////
Console.WriteLine(“-------------------------------------------------------------”;
Console.WriteLine(“单线程进程”);
Console.WriteLine(“-------------------------------------------------------------”;
WriteLine(“进程时间线程ID”);
Console.WriteLine(“-------------------------------------------------------------”;
秒表复位();
秒表。开始();
//对于仅使用1个线程的每个法线
foreach(时间数据中的int i)
{
过程(一);
}
秒表;
//程序执行该过程所需的总时间
控制台写入线(“*总计:+秒表已用);
////--------------------------多重------------------------------/////
Console.Write(procName);