我想对C#进行测试(我想将它的运行速度与另一种语言进行比较) 我想要做的是在链中创建100,000个线程,让每个线程在它之前等待来自线程的值,当它获得值add 1并将值传递给下一个线程时。 我们的想法是看它创建这些线程的速度有多快,最多可以增加100,000个 我不知道如何编写该代码。我可以像线程和计时一样做它的一部分,但我不确定如何将它们串在一起。
修改
在线程方面,我似乎也可以了解我的知识缺陷。那么让我们假设Thread Pooling(或其他一些低级方法)具有可比性,是否可以有人向我展示其中的示例?
答案 0 :(得分:7)
这种情况正是TPL旨在实现的目标,特别是C#5用语中的ContinueWith
或await
。请注意,async!= threading(尽管它们是相关的),但重点是您实际上是在尝试执行100k 任务,而不是100k 线程。这两个概念是不同的。 TPL是执行此操作的正确方法。始终使用适当的工具来完成工作。
如果你想要的话,我会高兴地提出一个TPL例子:
var root = new Task<int>(() => 0);
var end = root;
for(int i = 0 ; i < 100000 ; i++)
{
end = end.ContinueWith(last => last.Result + 1);
}
var watch = Stopwatch.StartNew();
root.Start();
end.Wait();
watch.Stop();
Console.WriteLine("{0} in {1}ms", end.Result, watch.ElapsedMilliseconds);
答案 1 :(得分:3)
好的,只是出于讨论目的,而不是真正的基准:
const int numberOfTasks = 100000;
int total = 0;
var watch = System.Diagnostics.Stopwatch.StartNew();
Parallel.For(0, numberOftasks, (i) => Interlocked.Increment(ref total));
var elapsed = watch.Elapsed;
这包括加入所有任务和聚合例外。
在我的双核笔记本电脑上,在调试模式下需要0.004秒。
答案 2 :(得分:2)
我不清楚你究竟想要衡量什么。您可以轻松地使用Task
来编写代码进行计算:
var initial = new Task<int>(() => 0);
var task = initial;
for (int i = 0; i < 100000; i++)
task = task.ContinueWith(t => t.Result + 1);
var watch = new Stopwatch();
watch.Start();
initial.Start();
task.Wait();
watch.Stop();
Console.WriteLine(task.Result);
Console.WriteLine(watch.Elapsed);
此代码看起来像您想要的代码,在我的计算机上执行它需要大约0.10秒。这几乎是无用的数字,主要是因为它根本不测试多线程。所有任务都在同一个线程上一个接一个地运行,因为在您的示例中绝对不需要并行性。
当然,这并不表明C#是比Go更好的语言。所有这些表明,你应该测试这样的例子,这些例子至少类似于某些人会觉得有用的东西。
答案 3 :(得分:0)
在main函数中,在循环中创建这些线程而不运行它们。在此期间,让线程i等待线程i-1退出。循环完成后,只需启动您创建的第一个线程(例如,线程1)(只需等待线程2等待)。它们将逐一启动。
答案 4 :(得分:0)
你可能会崩溃Windows。
您需要创建一个具有Thread
成员变量并使用Linked Lists
的类。
在您的类构造函数中,它应该采用前一个线程的Thread.ID
和您的Count
索引。
当你的类被创建时,它的构造函数需要检查Count
值,如果它不到100,000,则创建另一个类。
答案 5 :(得分:-1)
使用System; 使用System.Threading;
命名空间ConsoleApplication1 { 课程 {
static int X;
static void Main(string[] args)
{
const int INT_Constant = 1000;
var threads = new Thread[INT_Constant];
for (var i = 0; i < INT_Constant; i++)
{
threads[i] = new Thread(RunThread);
}
threads[0].Start();
for (var i = 1; i < INT_Constant; i++)
{
threads[i].Start(threads[i - 1]);
}
threads[INT_Constant - 1].Join();
}
static void RunThread(object state)
{
var previousThread = (Thread)state;
if (previousThread != null)
previousThread.Join();
X += 1;
Console.WriteLine("Thread # " + Thread.CurrentThread.ManagedThreadId + " updated X to " + X);
}
}
}
答案 6 :(得分:-1)
使用System; 使用System.Threading;
命名空间ConsoleApplication1 { 课程 {
static int X;
static object SyncRoot = new object();
static void Main(string[] args)
{
const int INT_Constant = 1000;
var threads = new Thread[INT_Constant];
for (var i = 0; i < INT_Constant; i++)
{
threads[i] = new Thread(RunThread);
}
lock (SyncRoot)
{
threads[0].Start();
for (var i = 1; i < INT_Constant; i++)
{
threads[i].Start(threads[i - 1]);
}
}
threads[INT_Constant - 1].Join();
}
static void RunThread(object state)
{
var previousThread = (Thread)state;
if (previousThread != null)
previousThread.Join();
else
lock (SyncRoot)
{
Console.WriteLine("Starting now");
}
X += 1;
Console.WriteLine("Thread # " + Thread.CurrentThread.ManagedThreadId + " updated X to " + X);
}
}
}