随笔 - 54  文章 - 2 评论 - 79 阅读 - 69803
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5


      在一些测试工作时我们需要获得高精度的代码执行时间以比较其效率。最近遇到一个模块其执行时间非常短,但是调用频率非常高。精确计算其运算时间对于提高程序整体效率来说非常重要。

      在我刚刚接触.Net时,也曾经想要测试一下自己写的程序的运行时间,当时我使用的是将两个DateTime.Now相减的笨方法,呵呵。后来知道使用Environment.TickCount,对于一般的测试来说就足够了。但是它对于高精度测试就没什么办法,经常是返回个0了事。对于高精度测试我们应当使用QueryPerformanceFrequency函数和QueryPerformanceCounter函数。通过它们可以获得比Environment.TickCount更高的精确度。实际上Environment.TickCount就是在调用QueryPerformanceFrequency函数和QueryPerformanceCounter函数。

      下面是我使用的代码:

using System;

class Class1
{
    [System.Runtime.InteropServices.DllImport (
"Kernel32.dll")]
    
static extern bool QueryPerformanceCounter(ref long count);

    [System.Runtime.InteropServices.DllImport (
"Kernel32.dll")]
    
static extern bool QueryPerformanceFrequency(ref long count);

    [STAThread]
    
static void Main(string[] args)
    
{
        
long count = 0;
        
long count1 = 0;
        
long freq = 0;
        
double result = 0;
        
        QueryPerformanceFrequency(
ref freq);
        QueryPerformanceCounter(
ref count);

                
//需要测试的模块
        
        QueryPerformanceCounter(
ref count1);
        count 
= count1-count;
        result 
= (double)(count)/(double)freq;

        Console.WriteLine(
"耗时: {0} 秒", result);
        Console.ReadLine();
    }

}

      这样能够得到非常精确的结果。但是模块每次运行的时间总会有些误差,而当计算非常精确的时候,这些运行时间的误差也显得比较明显了。为此我对其进行循环多次测试使其误差平均化,通过多次测试的结果来进行执行效率的分析。

using System;

class Class1
{
    [System.Runtime.InteropServices.DllImport (
"Kernel32.dll")]
    
static extern bool QueryPerformanceCounter(ref long count);

    [System.Runtime.InteropServices.DllImport (
"Kernel32.dll")]
    
static extern bool QueryPerformanceFrequency(ref long count);

    [STAThread]
    
static void Main(string[] args)
    
{
        
long count = 0;
        
long count1 = 0;
        
long freq = 0;
        
double result = 0;
        
        QueryPerformanceFrequency(
ref freq);
        QueryPerformanceCounter(
ref count);

        
//开始的时候没有这层循环,所得数据浮动很大,添加这层循环来使得结果更加平均
        for (int i=0; i<500; i++
        
{
                
//需要测试的模块
        }

        
        QueryPerformanceCounter(
ref count1);

        count 
= count1-count;
        result 
= (double)(count)/(double)freq;

        Console.WriteLine(
"耗时: {0} 秒", result);
        Console.ReadLine();
    }

}




 

posted on   aiya  阅读(2689)  评论(3编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示