结果
锁定: 85.3微秒
Monitor.TryEnter: 11.0微秒
锁不是扩展成了相同的代码吗?
编辑: 1000次迭代的结果:锁定: 103.3微秒Monitor.TryEnter: 20.2微秒
下面的代码。谢谢
[Test]
public void Lock_Performance_Test()
{
const int lockIterations = 100;
Stopwatch csLock = Stopwatch.StartNew();
for (int i = 0; i < lockIterations; )
{
lock (object1)
{
i++;
}
}
csLock.Stop();
Stopwatch csMonitor = Stopwatch.StartNew();
for (int i = 0; i < lockIterations; )
{
if (Monitor.TryEnter(object1, TimeSpan.FromSeconds(10)))
{
try
{
i++;
}
finally
{
Monitor.Exit(object1);
}
}
}
csMonitor.Stop();
Console.WriteLine("Lock: {0:f1} microseconds", csLock.Elapsed.Ticks / 10M);
Console.WriteLine("Monitor.TryEnter: {0:f1} microseconds", csMonitor.Elapsed.Ticks / 10M);;
}
发布于 2010-03-10 20:29:32
可能是因为lock是Monitor.Enter,而不是Monitor.TryEnter?
发布于 2010-03-10 20:45:07
您可以使用.NET反射器来检查生成的IL。lock
关键字使用Monitor.Enter
而不是Monitor.TryEnter
-这是您问题的简短答案。下面是您的代码在反汇编并转换回C#时的样子:
public void Lock_Performance_Test()
{
Stopwatch csLock = Stopwatch.StartNew();
int i = 0;
while (i < 100)
{
object CS$2$0000;
bool <>s__LockTaken0 = false;
try
{
Monitor.Enter(CS$2$0000 = this.object1, ref <>s__LockTaken0);
i++;
}
finally
{
if (<>s__LockTaken0)
{
Monitor.Exit(CS$2$0000);
}
}
}
csLock.Stop();
Stopwatch csMonitor = Stopwatch.StartNew();
i = 0;
while (i < 100)
{
if (Monitor.TryEnter(this.object1, TimeSpan.FromSeconds(10.0)))
{
try
{
i++;
}
finally
{
Monitor.Exit(this.object1);
}
}
}
csMonitor.Stop();
Console.WriteLine("Lock: {0:f1} microseconds", csLock.Elapsed.Ticks / 10M);
Console.WriteLine("Monitor.TryEnter: {0:f1} microseconds", csMonitor.Elapsed.Ticks / 10M);
}
发布于 2016-04-09 02:12:23
如果你需要速度,那么根据我的经验,SpinLock是一个更好的选择。
public class DisposableSpinLock : IDisposable {
private SpinLock mylock;
private bool isLocked;
public DisposableSpinLock( SpinLock thelock ) {
this.mylock = thelock;
mylock.Enter( ref isLocked );
}
public DisposableSpinLock( SpinLock thelock, bool tryLock) {
this.mylock = thelock;
if( tryLock ) {
mylock.TryEnter( ref isLocked );
} else {
mylock.Enter( ref isLocked );
}
}
public bool IsLocked { get { return isLocked; } }
public void Dispose() {
Dispose( true );
GC.SuppressFinalize( this );
}
protected virtual void Dispose( bool disposing ) {
if( disposing ) {
if( isLocked ) {
mylock.Exit();
}
}
}
}
是在中止和异常情况下让事情“自动”工作的一种非常有用的方法。
您可以只创建一个锁而不是“SpinLock”对象,然后使用:
using( new DisposableSpinLock( myLock ) ) {
// Under lock and key...
}
这允许您获得lock()提供的相同单行代码,同时还处理所需的try {} finally{}行为,并对清理对象所发生的事情有更多的控制。
我还支持"try“用例,它将使用内部带有额外if语句的代码块来编写:
using( theLock = new DisposableSpinLock( myLock, true ) ) {
if( theLock.IsLocked ) {
// Under Lock and Key
}
}
对于高度争用的锁,SpinLock并不是CPU友好的,因为在这种情况下会增加SpinLock的CPU使用率,但对于那些几乎同步的锁,并且只需要偶尔锁定外部引用或偶尔访问第二个线程,这是一个很大的胜利。
是的,这并不华丽,但对我来说,SpinLocks让我为轻度争用的锁提供的所有东西都更有性能。
http://www.adammil.net/blog/v111_Creating_High-Performance_Locks_and_Lock-free_Code_for_NET_.html是一个很好的自旋锁和整体锁定的例子。
https://stackoverflow.com/questions/2416793
复制相似问题