结果
锁定: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);;
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*Tao 31
我实际上并不知道答案,但觉得指出这一点lock并且Monitor.TryEnter在功能上并不相同是很重要的.从MSDN文档Monitor.TryEnter:
如果成功,则此方法获取obj参数的独占锁定.无论锁是否可用,此方法都会立即返回.
该lock语句类似于Monitor.Enter,这不会潜在地阻塞.当然,在您的示例代码中,不应存在任何阻塞问题; 但我会打赌,因为lock提供阻止,它做的(可能)比做更多的工作TryEnter.
为了它的价值,我只是在我的机器上尝试了你的代码并获得了完全不同的结果:
100次迭代::
lock4.4微秒
Monitor.TryEnter:16.1微秒
Monitor.Enter:3.9微秒
100000次迭代::
lock2872.5微秒
Monitor.TryEnter:5226.6微秒
Monitor.Enter:2432.9微秒
这严重破坏了我最初的猜测,并表明,在我的系统上,lock(其性能大致相同Monitor.Enter)实际上表现得非常好 Monitor.TryEnter.
实际上,我在针对.NET 3.5和.NET 4.0的VS 2010中尝试了这一点,尽管结果不同,但在每种情况下lock确实都表现优异Monitor.TryEnter:
运行100次,每次100000次迭代:
锁定:279736.4微秒
Monitor.TryEnter:1366751.5微秒
Monitor.TryEnter(无超时):475107.3微秒
Monitor.Enter:332334.1微秒
运行100次,每次100000次迭代:
锁定:334273.7微秒
Monitor.TryEnter:1671363.4微秒
Monitor.TryEnter(无超时):531451.8微秒
Monitor.Enter:316693.1微秒
(请注意,我还测试了Monitor.TryEnter,没有超时,因为我与马克认为,呼吁TimeSpan.FromSeconds几乎肯定放慢您的时间Monitor.TryEnter-并且这些测试支持-尽管这很奇怪,因为在你的情况下,显然lock是依然.显著慢)
基于这些结果,我强烈倾向于认为通过使用Test属性运行此代码会影响您的测量执行时间.无论是那个代码还是这个代码都比我预期的更依赖于机器.
100太少了,在测试框架中运行可能会使内容歪斜。这也可能(参见注释)与与对对象的第一次锁定相关的任何额外费用有关;尝试:
另外,请注意,在4.0 lock中不是 Monitor.Enter(object) -因此期望在4.0中获得不同的结果。
但是我得到:
lock: 3548ms
Monitor.TryEnter: 7008ms
Monitor.TryEnter (2): 2947ms
Monitor.Enter: 2906ms
Run Code Online (Sandbox Code Playgroud)
从测试台:
using System;
using System.Diagnostics;
using System.Threading;
static class Program {
static void Main()
{
const int lockIterations = 50000000;
object object1 = new object();
lock (object1) { Console.WriteLine("First one has to pay an extra toll"); }
Stopwatch csLock = Stopwatch.StartNew();
for (int i = 0; i < lockIterations; ) {
lock (object1) { i++; }
}
csLock.Stop();
Console.WriteLine("lock: " + csLock.ElapsedMilliseconds + "ms");
Stopwatch csMonitorTryEnter = Stopwatch.StartNew();
for (int i = 0; i < lockIterations; ) {
if (Monitor.TryEnter(object1, TimeSpan.FromSeconds(10))) {
try { i++; } finally { Monitor.Exit(object1); }
}
}
csMonitorTryEnter.Stop();
Console.WriteLine("Monitor.TryEnter: " + csMonitorTryEnter.ElapsedMilliseconds + "ms");
csMonitorTryEnter = Stopwatch.StartNew();
for (int i = 0; i < lockIterations; ) {
if (Monitor.TryEnter(object1, 10000)) {
try { i++; } finally { Monitor.Exit(object1); }
}
}
csMonitorTryEnter.Stop();
Console.WriteLine("Monitor.TryEnter (2): " + csMonitorTryEnter.ElapsedMilliseconds + "ms");
Stopwatch csMonitorEnter = Stopwatch.StartNew();
for (int i = 0; i < lockIterations; ) {
Monitor.Enter(object1);
try { i++; } finally { Monitor.Exit(object1); }
}
csMonitorEnter.Stop();
Console.WriteLine("Monitor.Enter: " + csMonitorEnter.ElapsedMilliseconds + "ms");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15232 次 |
| 最近记录: |