Welcome

首页 / 软件开发 / C# / 利用静态只读字段和静态构造函数提高性能

利用静态只读字段和静态构造函数提高性能2011-06-28 博客园 xuefly主要内容一句话概括:

把相对固定的数据在编译时仅通过查询一次数据库填充到公开的静态只读泛型集合类型字段中从而杜绝后续可能的数据库查询以提高性能。

相关背景:我们的应用程序中常常需要一些类似全国的省份列表这样的集合数据,而这些数据基本上是固定不变的或者是很长时间才会变一次。对于这样的数据,开发中我们常用的一个做法就是把这些数据存在数据库表中,然后查询填充到需要的地方。我觉得这种做法很脏,因为我们多次去查询这些固定不变的数据没有什么意义,或者进一步我们顶多缓存这些数据以避免一些查询以提高性能,也就是利用了单件模式的原理(我对模式不太熟悉,感觉缓存好像是跟单件模式本质一样,不知道这样理解是否得当,希望回帖指证我啊)。但是无论缓存和单件模式都需要额外的逻辑(缓存方案需要有判断缓存数据是否存在,添加过期策略等逻辑;单件模式也必须有拥有类似的逻辑)这些逻辑虽然简单但也影响性能。

解决方案:

用静态只读字段存储数据,在静态构造函数内连接数据库完成数据查询,将数据赋给类的静态只读字段。下面摘自MSDN对静态构造函数的说明:

静态构造函数(C# 编程指南)

静态构造函数用于初始化任何静态数据,或用于执行仅需执行一次的特定操作。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。

MSDN连接地址:http://msdn.microsoft.com/zh-cn/library/k9x6w0hc(VS.80).aspx

示例代码:

Certificate是“证书类”

CertificateTypes是“证书类型”型的泛型集合

CertificateDictionary是字典,键是证书类型ID,值是对应证书类型下的证书集合

public static class Certificate
{
public static readonly IList<CertificateType> CertificateTypes = new List<CertificateType>();
public static readonly IDictionary<int, IList<CertificateList>> CertificateDictionary = new Dictionary<int, IList<CertificateList>>();

private static readonly ICertificate dal = DataAccess.CreateCertificate();

static Certificate()
{
CertificateTypes = dal.GetCertificateTypes();
foreach (CertificateType item in CertificateTypes)
{
CertificateDictionary.Add(item.ID, dal.GetCertificateListByCertificateTypeID(item.ID));
}
}
}

该方案的问题:因为数据是在编译的时候得到的,得到以后就跟数据库没有任何关系了(感兴趣的朋友可以通过SQL Sever的事件探查器跟踪一下,时间探查器在SQL Server 2005中的新名字是SQL Server profiler)也就是说如果有一天中国把日本变成了第35个省的话,你把日本添加到省份列表数据库表后需要重新编译一下应用程序才能显示出来。目前我知道的可以让应用程序重新编译的方法是:想办法改变Web.config文件的时间项,比如原封不动的覆盖一次(重启Application会丢失全部会话,请慎用)。哪位朋友有好的方法可以通过编程让应用程序自动重启的话回复给我哈

总结:如果你的团队有时间硬编来码构造类似全国的县市列表这样的集合的话就不需要使用数据库了,上面的解决方案也就不适合你了。需要说明的一点是上面的方法本质也是通过硬编码构造集合。

希望对您有用