获取高精度的时间差,可以用来分析页面运行时间的长短

DateTime.Now的精度是很低,这个低的意思是,两次获取的DateTime.Now的Ticks的差,只是一个较大数的整数倍。例如在我的机器上,这个差最小是10.114ms。所以,如果我用DateTime.Now来计算时间差,那么就无法精确到10ms以内。

后来发现ASP.NET的TRACE的精度很高,用Reflector看它的实现,发现了它是使用这两个方法的:

参考MSDN:How To: Time Managed Code Using QueryPerformanceCounter and QueryPerformanceFrequency

我自己了按照这个写了个类,代码如下

using System;
using System.Runtime.InteropServices;
public class A
{
[DllImport("kernel32.dll")]
static extern bool QueryPerformanceCounter([In, Out] ref long lpPerformanceCount);
[DllImport("kernel32.dll")]
static extern bool QueryPerformanceFrequency([In, Out] ref long lpFrequency);

static long _f = 0;

static public long GetTickCount()
{
long f = _f;

if (f == 0)
{
if (QueryPerformanceFrequency(ref f))
{
_f = f;
}
else
{
_f = -1;
}
}
if (f == -1)
{
return Environment.TickCount * 10000;
}
long c = 0;
QueryPerformanceCounter(ref c);
return (long)(((double)c) * 1000 * 10000 / ((double)f));
}

//GetTickCount()为0时的DateTime.Ticks值
static long _tc = 0;

//这个返回的不是真正的精确时间,但时间与时间的差是精确的。
//GetExactNow与DateTime.Now的偏差比DateTime.Now的精度还要小,所以该偏差
static public DateTime GetExactNow()
{
if (_tc == 0)
{
long tc = GetTickCount();
DateTime dt = DateTime.Now;
_tc = dt.Ticks - tc;
return dt;
}

return new DateTime(_tc + GetTickCount());
}
}


在ASP。NET的应用,可以在Global.asax的Application_BeginRequest事件中加入代码来纪录程序开始时的TickCount:

Context.Items["BeginRequestTickCount"]=A.GetTickCount();


然后在页面输出的后面:

<html>....
<div align="center">
<%=new TimeSpan(A.GetTickCount()-(long)Context.Items["BeginRequestTickCount"]).TotalMilliseconds%>
</div>
</body></html>


这样就可以达到获取页面运行时间值了。(当然输出TotalMilliseconds后Asp.Net还要一些后期工作的,不过这个时间应该只需要0.n ms)DateTime.Now的精度是很低,这个低的意思是,两次获取的DateTime.Now的Ticks的差,只是一个较大数的整数倍。例如在我的机器上,这个差最小是10.114ms。所以,如果我用DateTime.Now来计算时间差,那么就无法精确到10ms以内。

后来发现ASP.NET的TRACE的精度很高,用Reflector看它的实现,发现了它是使用这两个方法的:

参考MSDN:How To: Time Managed Code Using QueryPerformanceCounter and QueryPerformanceFrequency

我自己了按照这个写了个类,代码如下

using System;
using System.Runtime.InteropServices;
public class A
{
[DllImport("kernel32.dll")]
static extern bool QueryPerformanceCounter([In, Out] ref long lpPerformanceCount);
[DllImport("kernel32.dll")]
static extern bool QueryPerformanceFrequency([In, Out] ref long lpFrequency);

static long _f = 0;

static public long GetTickCount()
{
long f = _f;

if (f == 0)
{
if (QueryPerformanceFrequency(ref f))
{
_f = f;
}
else
{
_f = -1;
}
}
if (f == -1)
{
return Environment.TickCount * 10000;
}
long c = 0;
QueryPerformanceCounter(ref c);
return (long)(((double)c) * 1000 * 10000 / ((double)f));
}

//GetTickCount()为0时的DateTime.Ticks值
static long _tc = 0;

//这个返回的不是真正的精确时间,但时间与时间的差是精确的。
//GetExactNow与DateTime.Now的偏差比DateTime.Now的精度还要小,所以该偏差
static public DateTime GetExactNow()
{
if (_tc == 0)
{
long tc = GetTickCount();
DateTime dt = DateTime.Now;
_tc = dt.Ticks - tc;
return dt;
}

return new DateTime(_tc + GetTickCount());
}
}


在ASP。NET的应用,可以在Global.asax的Application_BeginRequest事件中加入代码来纪录程序开始时的TickCount:

Context.Items["BeginRequestTickCount"]=A.GetTickCount();


然后在页面输出的后面:

<html>....
<div align="center">
<%=new TimeSpan(A.GetTickCount()-(long)Context.Items["BeginRequestTickCount"]).TotalMilliseconds%>
</div>
</body></html>


这样就可以达到获取页面运行时间值了。(当然输出TotalMilliseconds后Asp.Net还要一些后期工作的,不过这个时间应该只需要0.n ms)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值