我是一个完全的新手,但是我正在编写一个在 C# 中处理字符串的小程序,我注意到如果我做一些不同的事情,代码执行得更快。
所以我想知道,你如何为你的代码的执行速度计时?是否有任何(免费)实用程序?您是否使用 System.Timer 以老式方式进行操作并自己进行操作?
我是一个完全的新手,但是我正在编写一个在 C# 中处理字符串的小程序,我注意到如果我做一些不同的事情,代码执行得更快。
所以我想知道,你如何为你的代码的执行速度计时?是否有任何(免费)实用程序?您是否使用 System.Timer 以老式方式进行操作并自己进行操作?
您所描述的称为性能分析。您可以使用许多程序来执行此操作,例如Jetbrains profiler或Ants profiler,尽管大多数程序会在测量其性能的过程中减慢您的应用程序的速度。
要手动滚动您自己的性能分析,您可以使用System.Diagnostics.Stopwatch和一个简单的 Console.WriteLine,就像您描述的那样。
还要记住,C# JIT 编译器会根据调用的类型和频率来优化代码,因此请尝试使用不同大小的循环和方法(例如递归调用)来了解最有效的方法。
RedGate 的 ANTS Profiler是一个非常好的性能分析器。JetBrains 的 dotTrace Profiler也很棒。这些工具将允许您查看可以深入到每条线的性能指标。
ANTS Profiler 的屏幕截图: ANTS http://www.red-gate.com/products/ants_profiler/images/app/timeline_calltree3.gif
如果您想确保特定方法在单元测试期间保持在特定性能阈值内,我会使用Stopwatch
该类在循环中多次监视方法的执行时间并计算平均值,然后Assert
针对结果。
只是提醒一下 - 确保在 Relase 中编译,而不是在 Debug 中编译!(我见过经验丰富的开发人员犯的这个错误——很容易忘记)。
您所描述的是“性能调整”。当我们谈论性能调整时,有两个角度。(a) 响应时间——执行特定请求/程序需要多长时间。(b) 吞吐量——它可以在一秒钟内执行多少个请求。当我们通常“优化”时 - 当我们消除不必要的处理时,响应时间和吞吐量都会提高。但是,如果您的代码中有等待事件(如 Thread.sleep()、I/O 等待等),您的响应时间会受到影响,但吞吐量不会受到影响。通过采用并行处理(产生多个线程),我们可以提高响应时间,但不会提高吞吐量。通常对于服务器端应用程序,响应时间和吞吐量都很重要。对于桌面应用程序(如 IDE),吞吐量并不重要,只有响应时间很重要。
您可以通过“性能测试”来衡量响应时间——您只需记下所有关键事务的响应时间。您可以通过“负载测试”来测量吞吐量 - 您需要从足够多的线程/客户端连续抽取请求,以使服务器计算机的 CPU 使用率为 80-90%。当我们提出请求时,我们需要保持不同交易之间的比率(称为交易组合) - 例如:在预订系统中,每 100 次搜索将有 10 次预订。每 10 次预订将取消一次,等等。
在确定事务需要调整响应时间(性能测试)后,您可以使用分析器来确定热点。您可以通过比较该事务的响应时间 * 分数来识别吞吐量的热点。假设在搜索、预订、取消场景中,比例为 89:10:1。响应时间为 0.1 秒、10 秒和 15 秒。搜索负载- 0.1 * .89 = 0.089 预订负载- 10 * .1 = 1 取消负载= 15 * .01= 0.15 这里调整预订将对吞吐量产生最大影响。您还可以通过重复进行线程转储(在基于 Java 的应用程序的情况下)来识别吞吐量的热点。
使用分析器。
如果您只需要对一种特定方法计时,则 Stopwatch 类可能是一个不错的选择。
我做了以下事情: 1)我使用刻度(例如在 VB.Net Now.ticks 中)来测量当前时间。我从完成的刻度值中减去起始刻度,然后除以 TimeSpan.TicksPerSecond 以获得它花费了多少秒。2) 我避免 UI 操作(如 console.writeline)。3)我在一个实质性的循环(如 100,000 次迭代)上运行代码,以尽可能地排除使用/操作系统变量。
您可以使用 StopWatch 类对方法进行计时。请记住,由于必须对代码进行 jit,第一次通常很慢。
有一个本机 .NET 选项(软件开发人员的团队版)可以解决一些性能分析需求。从 2005 .NET IDE 菜单中,选择工具->性能工具->性能向导...
[GSS可能是正确的,你必须有团队版]
这是测试代码速度的简单示例。我希望我帮助了你
class Program {
static void Main(string[] args) {
const int steps = 10000;
Stopwatch sw = new Stopwatch();
ArrayList list1 = new ArrayList();
sw.Start();
for(int i = 0; i < steps; i++) {
list1.Add(i);
}
sw.Stop();
Console.WriteLine("ArrayList:\tMilliseconds = {0},\tTicks = {1}", sw.ElapsedMilliseconds, sw.ElapsedTicks);
MyList list2 = new MyList();
sw.Start();
for(int i = 0; i < steps; i++) {
list2.Add(i);
}
sw.Stop();
Console.WriteLine("MyList: \tMilliseconds = {0},\tTicks = {1}", sw.ElapsedMilliseconds, sw.ElapsedTicks);