C# WaitHandle同步有多贵?
我听说,C# WaitHandle同步有多贵?,c#,performance,synchronization,C#,Performance,Synchronization,我听说,WaitHandle派生的同步原语很昂贵,但找不到进一步的细节。是否有与其他等效或类似原语的性能比较?对于一种特殊情况,如果可以互换AutoResetEvent和Monitor,监视器的性能至少提高1.5倍(通常为2倍)。此语句基于以下原始生产者/消费者测试(发布构建),在测试逻辑中没有错误的情况下有效:o)无论如何,可能对某人有用 现在,我正努力成为;) 代码: using System; using System.Collections.Generic; using System.D
WaitHandle
派生的同步原语很昂贵,但找不到进一步的细节。是否有与其他等效或类似原语的性能比较?对于一种特殊情况,如果可以互换AutoResetEvent
和Monitor
,监视器的性能至少提高1.5倍(通常为2倍)。此语句基于以下原始生产者/消费者测试(发布构建),在测试逻辑中没有错误的情况下有效:o)无论如何,可能对某人有用
现在,我正努力成为;)
代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Timer = System.Timers.Timer;
namespace ThreadSync2
{
static class Measurement
{
private static readonly Random rng = new Random();
private static long Evaluate(string methodName, Action signal, Action wait)
{
var isProducing = false;
var isConsuming = false;
var mtxData = new object();
var data = new Queue<Tuple<long,int>>();
var produced = 0L;
var consumed = 0L;
var watch = new Stopwatch();
var producer = new Thread(() =>
{
Debug.WriteLine("Production : started.");
while (isProducing)
{
var item = rng.Next(0, 100);
lock (mtxData)
data.Enqueue(new Tuple<long, int>(produced, item));
signal();
Debug.WriteLine($"{watch.Elapsed.Seconds,3:d}.{watch.Elapsed.Milliseconds:d3} Producer: {produced,6:d} [{item,3:d}]");
++produced;
}
Debug.WriteLine("Production : finished.");
}){Name = "Producer"};
var consumer = new Thread(() =>
{
Debug.WriteLine("Consumption: started.");
while ( (isConsuming)
|| (data.Count > 0))
{
while (data.Count > 0)
{
Tuple<long, int> record;
lock (mtxData)
record = data.Dequeue();
Debug.WriteLine($"{watch.Elapsed.Seconds,3:d}.{watch.Elapsed.Milliseconds:d3} Consumer: {record.Item1,6:d} [{record.Item2,3:d}]");
++consumed;
}
wait();
}
Debug.WriteLine("Consumption: finished.");
}){Name = "Consumer"};
var timer = new Timer(5000){AutoReset = false};
timer.Elapsed += (s, e) => {isProducing = false;};
Console.WriteLine($"Evaluating \"{methodName}\"...");
watch.Start();
timer.Enabled = true;
isConsuming = true;
isProducing = true;
consumer.Start();
producer.Start();
producer.Join();
isConsuming = false;
consumer.Join();
watch.Stop();
Console.WriteLine($"Produced items: {produced:### ### ##0}{((produced != consumed) ? $", Consumed items: {consumed:### ### ##0}" : "")}");
Console.WriteLine();
return produced;
}
public static void Evaluate()
{
const string strMonitorLock = "Monitor locking";
const string strWaitHandle = "AutoResetEvent";
const int waitTimeout = 500;
var semMonitorLock = new object();
var semWaitHandle = new AutoResetEvent(false);
var cntMonitorLock = Evaluate
(
strMonitorLock,
() => {lock (semMonitorLock) Monitor.Pulse(semMonitorLock);},
() => {lock (semMonitorLock) Monitor.Wait (semMonitorLock, waitTimeout);}
);
var cntWaitHandle = Evaluate
(
strWaitHandle,
() => semWaitHandle.Set(),
() => semWaitHandle.WaitOne(waitTimeout)
);
Console.WriteLine($"{strMonitorLock} / {strWaitHandle} = {((double)cntMonitorLock / cntWaitHandle):0.000}");
Console.WriteLine();
}
}
class Program
{
static Program()
{
Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
}
static void Main(string[] args)
{
Measurement.Evaluate();
}
}
}
Evaluating "Monitor locking"...
Produced items: 15 710 306
Evaluating "AutoResetEvent"...
Produced items: 5 998 742
Monitor locking / AutoResetEvent = 2,619
Evaluating "Monitor locking"...
Produced items: 11 697 953
Evaluating "AutoResetEvent"...
Produced items: 7 119 778
Monitor locking / AutoResetEvent = 1,643
Evaluating "Monitor locking"...
Produced items: 11 662 575
Evaluating "AutoResetEvent"...
Produced items: 6 437 772
Monitor locking / AutoResetEvent = 1,812
Evaluating "Monitor locking"...
Produced items: 12 981 254
Evaluating "AutoResetEvent"...
Produced items: 5 934 954
Monitor locking / AutoResetEvent = 2,187
Evaluating "Monitor locking"...
Produced items: 14 661 293
Evaluating "AutoResetEvent"...
Produced items: 6 370 518
Monitor locking / AutoResetEvent = 2,301
Evaluating "Monitor locking"...
Produced items: 15 050 786
Evaluating "AutoResetEvent"...
Produced items: 5 912 671
Monitor locking / AutoResetEvent = 2,546
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用系统线程;
使用定时器=System.Timers.Timer;
命名空间线程同步2
{
静态等级测量
{
私有静态只读随机rng=new Random();
私有静态长评估(字符串方法名、操作信号、操作等待)
{
var isProducing=假;
var isConsuming=false;
var mtxData=新对象();
var data=新队列();
产生的var=0升;
消耗的var=0升;
var watch=新秒表();
var producer=新线程(()=>
{
WriteLine(“生产:已启动”);
同时(生产)
{
var项目=下一个(0,100)rng;
锁(mtxData)
排队(新元组(生成的,项));
信号();
Debug.WriteLine($“{watch.appeased.Seconds,3:d}.{watch.appeased.ms:d3}生产者:{producted,6:d}[{item,3:d}]”);
++产生;
}
Debug.WriteLine(“生产:完成”);
}){Name=“Producer”};
var consumer=新线程(()=>
{
WriteLine(“消费:已启动”);
while((正在消费)
||(data.Count>0)
{
而(data.Count>0)
{
元组记录;
锁(mtxData)
record=data.Dequeue();
Debug.WriteLine($“{watch.appeased.Seconds,3:d}.{watch.appeased.ms:d3}使用者:{record.Item1,6:d}[{record.Item2,3:d}]”;
++消耗;
}
等待();
}
Debug.WriteLine(“消耗:完成”);
}){Name=“Consumer”};
var定时器=新定时器(5000){AutoReset=false};
timer.appeased+=(s,e)=>{isProducing=false;};
WriteLine($“evaluation\”{methodName}\”);
watch.Start();
timer.Enabled=true;
isConsuming=true;
isProducing=true;
consumer.Start();
producer.Start();
producer.Join();
isConsuming=false;
consumer.Join();
看,停;
Console.WriteLine($“生产的物品:{生产的:{生产的:{生产的:{0}{(生产的!=消费的)$”,消费的物品:{消费的:};
Console.WriteLine();
产生的回报;
}
公共静态void Evaluate()
{
常量字符串strMonitorLock=“监视器锁定”;
常量字符串strWaitHandle=“AutoResetEvent”;
常量int waitTimeout=500;
var semMonitorLock=新对象();
var semWaitHandle=新的自动重置事件(false);
var cntMonitorLock=评估
(
strMonitorLock,
()=>{lock(semMonitorLock)Monitor.Pulse(semMonitorLock);},
()=>{lock(semMonitorLock)Monitor.Wait(semMonitorLock,waitTimeout);}
);
var cntWaitHandle=评估
(
strWaitHandle,
()=>semWaitHandle.Set(),
()=>semWaitHandle.WaitOne(waitTimeout)
);
Console.WriteLine($“{strMonitorLock}/{strWaitHandle}={((双)cntMonitorLock/cntWaitHandle):0.000}”);
Console.WriteLine();
}
}
班级计划
{
静态程序()
{
添加(新的TextWriterTraceListener(Console.Out));
}
静态void Main(字符串[]参数)
{
测量。评估();
}
}
}
重复执行的控制台输出:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Timer = System.Timers.Timer;
namespace ThreadSync2
{
static class Measurement
{
private static readonly Random rng = new Random();
private static long Evaluate(string methodName, Action signal, Action wait)
{
var isProducing = false;
var isConsuming = false;
var mtxData = new object();
var data = new Queue<Tuple<long,int>>();
var produced = 0L;
var consumed = 0L;
var watch = new Stopwatch();
var producer = new Thread(() =>
{
Debug.WriteLine("Production : started.");
while (isProducing)
{
var item = rng.Next(0, 100);
lock (mtxData)
data.Enqueue(new Tuple<long, int>(produced, item));
signal();
Debug.WriteLine($"{watch.Elapsed.Seconds,3:d}.{watch.Elapsed.Milliseconds:d3} Producer: {produced,6:d} [{item,3:d}]");
++produced;
}
Debug.WriteLine("Production : finished.");
}){Name = "Producer"};
var consumer = new Thread(() =>
{
Debug.WriteLine("Consumption: started.");
while ( (isConsuming)
|| (data.Count > 0))
{
while (data.Count > 0)
{
Tuple<long, int> record;
lock (mtxData)
record = data.Dequeue();
Debug.WriteLine($"{watch.Elapsed.Seconds,3:d}.{watch.Elapsed.Milliseconds:d3} Consumer: {record.Item1,6:d} [{record.Item2,3:d}]");
++consumed;
}
wait();
}
Debug.WriteLine("Consumption: finished.");
}){Name = "Consumer"};
var timer = new Timer(5000){AutoReset = false};
timer.Elapsed += (s, e) => {isProducing = false;};
Console.WriteLine($"Evaluating \"{methodName}\"...");
watch.Start();
timer.Enabled = true;
isConsuming = true;
isProducing = true;
consumer.Start();
producer.Start();
producer.Join();
isConsuming = false;
consumer.Join();
watch.Stop();
Console.WriteLine($"Produced items: {produced:### ### ##0}{((produced != consumed) ? $", Consumed items: {consumed:### ### ##0}" : "")}");
Console.WriteLine();
return produced;
}
public static void Evaluate()
{
const string strMonitorLock = "Monitor locking";
const string strWaitHandle = "AutoResetEvent";
const int waitTimeout = 500;
var semMonitorLock = new object();
var semWaitHandle = new AutoResetEvent(false);
var cntMonitorLock = Evaluate
(
strMonitorLock,
() => {lock (semMonitorLock) Monitor.Pulse(semMonitorLock);},
() => {lock (semMonitorLock) Monitor.Wait (semMonitorLock, waitTimeout);}
);
var cntWaitHandle = Evaluate
(
strWaitHandle,
() => semWaitHandle.Set(),
() => semWaitHandle.WaitOne(waitTimeout)
);
Console.WriteLine($"{strMonitorLock} / {strWaitHandle} = {((double)cntMonitorLock / cntWaitHandle):0.000}");
Console.WriteLine();
}
}
class Program
{
static Program()
{
Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
}
static void Main(string[] args)
{
Measurement.Evaluate();
}
}
}
Evaluating "Monitor locking"...
Produced items: 15 710 306
Evaluating "AutoResetEvent"...
Produced items: 5 998 742
Monitor locking / AutoResetEvent = 2,619
Evaluating "Monitor locking"...
Produced items: 11 697 953
Evaluating "AutoResetEvent"...
Produced items: 7 119 778
Monitor locking / AutoResetEvent = 1,643
Evaluating "Monitor locking"...
Produced items: 11 662 575
Evaluating "AutoResetEvent"...
Produced items: 6 437 772
Monitor locking / AutoResetEvent = 1,812
Evaluating "Monitor locking"...
Produced items: 12 981 254
Evaluating "AutoResetEvent"...
Produced items: 5 934 954
Monitor locking / AutoResetEvent = 2,187
Evaluating "Monitor locking"...
Produced items: 14 661 293
Evaluating "AutoResetEvent"...
Produced items: 6 370 518
Monitor locking / AutoResetEvent = 2,301
Evaluating "Monitor locking"...
Produced items: 15 050 786
Evaluating "AutoResetEvent"...
Produced items: 5 912 671
Monitor locking / AutoResetEvent = 2,546
正在评估“监视器锁定”。。。
生产项目:15710306
正在评估“自动存储事件”。。。
生产项目:5998742
监视器锁定/自动重置事件=2619
正在评估“监视器锁定”。。。
生产项目:11697953
正在评估“自动存储事件”。。。
制作项目:7119778
监视器锁定/自动重置事件=1643
正在评估“监视器锁定”。。。
生产项目:11662575
正在评估“自动存储事件”。。。
制作项目:643772
监视器锁定/自动重置事件=1812
正在评估“监视器锁定”。。。
制作项目:12981254
正在评估“自动存储事件”。。。
生产项目:5934954
监视器锁定/自动重置事件=2187
正在评估“监视器锁定”。。。
制作项目:14661293
正在评估“自动存储事件”。。。
制作项目:6370518
监视器锁定/自动重置事件=2301
正在评估“监视器锁定”。。。
生产项目:15 050 786
正在评估“自动存储事件”。。。
生产项目:5912671
监视器锁定/自动重置事件=2546
好的测试代码。但是,我发现你对匈牙利符号的使用极其猥亵。它们涉及内核调用,这并不便宜。否则,必须确保