查看某些内容(例如方法调用)接受代码的最精确方式是什么?
我猜的最容易和最快的是:
DateTime start = DateTime.Now;
{
// Do some work
}
TimeSpan timeItTook = DateTime.Now - start;
Run Code Online (Sandbox Code Playgroud)
但这有多精确?还有更好的方法吗?
我有一个处理大量数据的高性能应用程序.它在很短的时间内接收,分析和丢弃大量信息.这导致我正在尝试优化的大量对象流失,但它也会导致次要问题.当垃圾收集进入时它可能会导致一些长时间的延迟,因为它清理了一些东西(长的意思是10到100毫秒).99%的时间这是可以接受的,但对于大约1-2分钟的短暂时间窗口,我需要绝对确定垃圾收集不会导致延迟.我知道这些时间段何时会事先发生,我只需要一种方法来确保在此期间不会发生垃圾收集.该应用程序使用.NET 4.0 Framework以C#编写,如果重要,则使用托管代码和非托管代码.
我的问题是;
注意 - 这个系统相当复杂,有很多不同的组件.我希望避免采用我必须在程序的每个类上实现自定义IDisposable接口的方法.
我正在使用DateTime对一行C#代码进行一些真正的快速和脏的基准测试:
long lStart = DateTime.Now.Ticks;
// do something
long lFinish = DateTime.Now.Ticks;
Run Code Online (Sandbox Code Playgroud)
问题在于结果:
Start Time [633679466564559902] Finish Time [633679466564559902] Start Time [633679466564569917] Finish Time [633679466564569917] Start Time [633679466564579932] Finish Time [633679466564579932]
...等等.
鉴于开始和结束时间相同,Ticks显然不够精细.
那么,我怎样才能更好地衡量绩效呢?
为什么.NET 4.0中的C#方法即时编译的顺序会影响它们执行的速度?例如,考虑两种等效方法:
public static void SingleLineTest()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int count = 0;
for (uint i = 0; i < 1000000000; ++i) {
count += i % 16 == 0 ? 1 : 0;
}
stopwatch.Stop();
Console.WriteLine("Single-line test --> Count: {0}, Time: {1}", count, stopwatch.ElapsedMilliseconds);
}
public static void MultiLineTest()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int count = 0;
for (uint i = 0; i < 1000000000; ++i) {
var isMultipleOf16 = i % …
Run Code Online (Sandbox Code Playgroud) 对不起,这是一个很长的问题,但我只是在分析这个问题时解释我的思路.最后的问题.
我已经了解了测量代码运行时间的方法.它运行多次以获得平均运行时间来计算每次运行的差异,并获得更好地利用缓存的时间.
为了测量某人的运行时间,我在多次修改后想出了这段代码.
最后,我最终得到了这个代码,它产生了我打算捕获的结果,而没有给出误导性的数字:
// implementation C
static void Test<T>(string testName, Func<T> test, int iterations = 1000000)
{
Console.WriteLine(testName);
Console.WriteLine("Iterations: {0}", iterations);
var results = Enumerable.Repeat(0, iterations).Select(i => new System.Diagnostics.Stopwatch()).ToList();
var timer = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < results.Count; i++)
{
results[i].Start();
test();
results[i].Stop();
}
timer.Stop();
Console.WriteLine("Time(ms): {0,3}/{1,10}/{2,8} ({3,10})", results.Min(t => t.ElapsedMilliseconds), results.Average(t => t.ElapsedMilliseconds), results.Max(t => t.ElapsedMilliseconds), timer.ElapsedMilliseconds);
Console.WriteLine("Ticks: {0,3}/{1,10}/{2,8} ({3,10})", results.Min(t => t.ElapsedTicks), results.Average(t => t.ElapsedTicks), results.Max(t => t.ElapsedTicks), timer.ElapsedTicks);
Console.WriteLine();
}
Run Code Online (Sandbox Code Playgroud)
在我看到的测量运行时间的所有代码中,它们通常采用以下形式: …
特定
IList<int> indexes;
ICollection<T> collection;
Run Code Online (Sandbox Code Playgroud)
什么是最优雅的方式来提取所有牛逼在收集基础上,提供的索引的索引?
例如,如果包含集合
"Brian", "Cleveland", "Joe", "Glenn", "Mort"
Run Code Online (Sandbox Code Playgroud)
并包含索引
1, 3
Run Code Online (Sandbox Code Playgroud)
回报将是
"Cleveland," "Glenn"
Run Code Online (Sandbox Code Playgroud)
编辑:假设索引始终按升序排序.
对于那些对我如何进行基准测试感兴趣的人,请看这里,我简单地在"Loop 1K"方法中替换/添加几个方法.
对不起,我忘了说我的测试环境..Net 4.5 x64(不要选择32位首选).在x86中,这两种方法的时间都是时间的5倍.
Loop2
花费的时间是3倍Loop
.我认为x++
/ x+=y
当x
变大时不应该减速(因为它需要1或2个cpu指令)
是因为参考地点?但是我认为在Loop2
变量不多的情况下,它们应该彼此接近......
public long Loop(long testSize)
{
long ret = 0;
for (long i = 0; i < testSize; i++)
{
long p = 0;
for (int j = 0; j < 1000; j++)
{
p+=10;
}
ret+=p;
}
return ret;
}
public long Loop2(long testSize)
{
long ret = 0;
for (long i = 0; i < testSize; i++) …
Run Code Online (Sandbox Code Playgroud) 是否可以通过.NET中的属性分析各个方法?
我目前正在尝试在大量遗留应用程序中找到一些瓶颈,这些应用程序大量使用静态方法.目前,集成框架根本不是一种选择.由于大多数调用都使用静态方法,因此接口和依赖注入不可用.攻击代码以记录诊断也不是一个可行的解决方案.
我知道市场上有一些分析工具,但它们目前不在预算范围内.理想情况下,我将能够创建自己的自定义属性,该属性将记录有关方法输入和方法退出的一些基本信息.我从来没有真正使用自定义属性,所以任何洞察甚至是否可能这将是值得赞赏的.
如果可能的话,我想通过配置文件启用分析.这将通过单元和集成测试支持分析.
我正在尝试提出一种方法来测量并返回另一种方法的执行时间.基本上是这样的:
__CODE__
签名,因此它的范围是-128..127而不是0..255.考虑到这一点,你的字节是正确的.如果字节的无符号值是__CODE__
,则有符号值是__CODE__
- 因此,对于__CODE__
有符号值是__CODE__
.