性能是考量一个控件产品好坏的重要指标,与产品的功能有着同等重要的地位。用户在选择一款控件产品的时候基本都会亲身试验比较同类产品的性能。作为选购那个控件重要因素之一。
控件的性能指什么
性能优化的原则
如何发现性能瓶颈
上一节提到,性能优化的第一步就是发现性能瓶颈,这一节主要介绍定位性能瓶颈的一些实践。
// 在这里写一些可能消耗内存的代码,例如,如果想了解创建一个GcMultiRow控件需要多少内存可以执行以下代码
long start = GC.GetTotalMemory(true);
var gcMulitRow1 = new GcMultiRow();
GC.Collect();
// 确保所有内存都被GC回收
GC.WaitForFullGCComplete();
long end = GC.GetTotalMemory(true);
long useMemory = end - start;
这里把一个操作循环执行了1000次,最后再把消耗的时间除以1000来确定最终消耗的时间。可以是结果更准确稳定,排除意外数据。
性能优化的方法和技巧
定位了性能问题后,解决的办法有很多。这个章节会介绍一些性能优化的技巧和实践。
for(int i = 0; i < gcMultiRow.RowCount; i++)
{
// Do something;
}
以上代码一般情况下是没有问题的,但是,如果GcMultiRow的行数比较大。而RowCount属性的取值又比较慢的时候就需要使用缓存来做性能优化。
int rowCount = gcMultiRow.RowCount; for (int i = 0; i < rowCount; i++) { // Do something; }public static class GDIPool
{
Dictionary<Color, Brush > _cacheBrush = new Dictionary<Color, Brush>();
Dictionary<Color, Pen> _cachePen = new Dictionary<Color, Pen>();
public static Pen GetPen(Color color)
{
Pen pen;
if_cachePen.TryGetValue(color, out pen))
{
return pen;
}
pen = new Pen(color);
_cachePen.Add(color, pen);
return pen;
}
}
一般做法下由于构造对象A的同时要构造对象B导致了A的构造速度也变慢了。优化做法:
public class A { private B _b; public B BProperty { get { if(_b == null) { _b = new B(); } return _b; } } }
操作 |
List |
Dictionary |
索引 |
快 |
慢 |
Find(Contains) |
慢 |
快 |
Add |
快 |
慢 |
Insert |
慢 |
快 |
Remove |
慢 |
快 |
当需要大量取值的时候,这样的取法会带来性能问题。优化方法如下:
object value; if(_dic.TryGetValue("Key", out value)) { return value; }使用TryGetValue可以比先Contain再取值提高一倍的性能。
这里比较慢的操作就是EnsureFunctions函数,是在另一个线程里执行的,不会影响主线程的响应。当然,使用多线程是一个比较有难度的方案,需要充分考虑跨线程访问和死锁的问题。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。