このコードは、マルチ スレッドとシングル スレッドの速度をテストする目的で作成しました。すべてのフィードバックに感謝します! いただいた素晴らしいコメントに基づいて、ほとんどを書き直しました。これは適切に機能するようになり (バグがあちこちにある可能性があります)、最初にマルチスレッドをテストし、より正確な速度を見つけるために平均を取ります: (下にスクロールして続きをご覧ください。)
メインメソッド クラス
using System;
namespace SingleAndMultiThreading
{
internal class Threads
{
private static void Main(string[] args)
{
long numOfObjCreated;
int numberOfTests;
while (true)
{
try
{
Console.Write("Number of objects to create: ");
numOfObjCreated = Convert.ToInt64(Console.ReadLine());
break;
}
catch (Exception)
{
Console.WriteLine("Invalid input.");
}
}
while (true)
{
try
{
Console.Write("Number of tests to run: ");
numberOfTests = Convert.ToInt32(Console.ReadLine());
break;
}
catch (Exception)
{
Console.WriteLine("Invalid input.");
}
}
CalculateResults(numOfObjCreated, numberOfTests);
Console.ReadKey();
}
private static void CalculateResults(long numOfObjCreated, int numberOfTests)
{
double totalPercentages = 0;
for (var i = 0; i < numberOfTests; i++)
{
totalPercentages += CompleteTests(numOfObjCreated);
}
var accuracy = totalPercentages / numberOfTests;
if ((int)accuracy == 0)
{
Console.WriteLine("\nIn this case, neither single threading or multithreading is faster.\n" +
"They both run equally well under these conditions.\n");
return;
}
if (accuracy < 0)
{
Console.WriteLine("\nIn this case with {0} objects being created, single threading is faster!\n",
string.Format("{0:#,###0}", numOfObjCreated));
return;
}
Console.WriteLine("\nFrom {0} test(s), {1}% was the average percentage of increased speed in multithreading.\n",
string.Format("{0:#,###0}", numberOfTests), string.Format("{0:#,###0}", accuracy));
}
private static double CompleteTests(long numOfObjCreated)
{
Console.WriteLine("Computing...");
var numOfCores = Environment.ProcessorCount;
var timeForMultiThread = MultiThread.Run(numOfObjCreated, numOfCores);
var timeForSingleThread = SingleThread.Run(numOfObjCreated);
var percentFaster = ((timeForSingleThread / timeForMultiThread) * 100) - 100;
//note: .NET does its part in assigning a certian thread to its own core
Console.WriteLine("Using all {0} cores, creating {1} objects is {2}% faster.",
numOfCores, string.Format("{0:#,###0}", numOfObjCreated), string.Format("{0:#,###0}", percentFaster));
return percentFaster;
}
}
}
シングルスレッドクラス
using System;
using System.Diagnostics;
namespace SingleAndMultiThreading
{
internal class SingleThread
{
public static double Run(long numOfObjCreated)
{
var watch = new Stopwatch();
watch.Start();
for (long i = 0; i < numOfObjCreated; i++)
{
new object();
}
watch.Stop();
var totalTime = watch.ElapsedTicks;
Console.WriteLine("The time to create {0} objects with 1 thread is: {1} ticks.",
string.Format("{0:#,###0}", numOfObjCreated), string.Format("{0:#,###0}", totalTime));
return totalTime;
}
}
}
マルチスレッドクラス
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace SingleAndMultiThreading
{
internal class MultiThread
{
public static double Run(long numOfObjCreated, int numOfCores)
{
var watch = new Stopwatch();
var workerObject = new Worker(numOfObjCreated / numOfCores);
var listOfThreads = new List<Thread>();
for (long k = 0; k < numOfCores; k++)
{
var workerThread = new Thread(workerObject.DoWork);
listOfThreads.Add(workerThread);
}
watch.Start();
foreach (var thread in listOfThreads)
{
thread.Start();
}
byte countOfCompletedThreads = 0;
while (true)
{
foreach (var thread in listOfThreads)
if (!thread.IsAlive)
countOfCompletedThreads++;
if (countOfCompletedThreads == numOfCores)
break;
countOfCompletedThreads = 0;
}
watch.Stop();
var totalTime = watch.ElapsedTicks;
Console.WriteLine("The time to create {0} objects utilizing all {1} cores is: {2} ticks.",
string.Format("{0:#,###0}", numOfObjCreated), numOfCores, string.Format("{0:#,###0}", totalTime));
return totalTime;
}
}
}
ワーカー クラス
namespace SingleAndMultiThreading
{
public class Worker
{
private readonly long _numOfObjToCreate;
public bool IsDone;
public Worker(long numOfObjToCreate)
{
_numOfObjToCreate = numOfObjToCreate;
}
public void DoWork()
{
for (long i = 0; i < _numOfObjToCreate; i++)
{
new object();
}
IsDone = true;
}
}
}
このコードの出力は、投稿するには少し長すぎます (自分の IDE にコピーして貼り付けることを強くお勧めします。これは非常に魅力的です)。これがすべてのテストで同じ結果をもたらさないという受け入れられた答えは、CPUスケジューリング、ASLRなどのその他またはマイナーな問題によるものだと思います。このプログラムを実行しているビジュアルスタジオ以外にも、複数のことが起こっており、優先順位が異なります。また、メモリ割り当てが既に行われているため、最初にマルチスレッドを実行すると役立つことを指摘していただきありがとうございます。
指摘すべきもう1つのことは、実行中にこれを見つけました:
スパイクは、マルチスレッドのプロセスが行われるときです。