首页 > 代码库 > Wpf吐槽第001次
Wpf吐槽第001次
很多初学者说.net性能不行。老鸟都知道这说法不确切,很多性能问题都是误用导致的,比如典型的没事就到处随地new临时对象,临时集合。
不过看过WPF的部分实现后才知道,WPF性能方面的设计和实现真的有问题! 本来也用不到wpf的,不过最近需要做些原型,需要功能简单性能还过得去的图形框架,就试了下wpf,紧接着就遇到各种难受的性能和设计问题。为了解决问题老老实实的查文档,实验,顺藤摸瓜用ILSpy看实现,才发现设计真的有问题,当年vista发布工期逼得太紧,明显设计没完工!
好吧,这就是个吐槽贴!
吐槽第一条,漫山遍野的double类型。很多地方完全没必要,甚至是不合适用double的也全都是double。这内存和计算开销不是平白翻倍了啊!不是我空口胡喷,有代码为证:
GlyphRun 类型,保存字符的,UI最基本的功能元素了吧。这个设计有问题。里面有个存字符宽度的private IList<double> _advanceWidths; 先不吐槽有没有必要每个字符都多存8个字节来描述宽度,看看这IList到底是啥类型的实例。 搜索这字段的赋值发现void ISupportInitialize.EndInit()里有 list = new ThousandthOfEmRealDoubles(this._renderingEmSize, this._advanceWidths);
这个名字牛逼哄哄的ThousandthOfEmRealDoubles是干嘛的呢?看实现得知
internal ThousandthOfEmRealDoubles(double emSize, IList<double> realValues)
{
this._emSize = emSize;
this.InitArrays(realValues.Count);
for (int i = 0; i < this.Count; i++)
{
this[i] = realValues[i];
}
}
注意,构造里调的是索引器赋值。
public double this[int index]{
get...
set {
if (this._shortList == null) {
this._doubleList[index] = value;
return;
}
short num;
if (this.RealToThousandthOfEm(value, out num)) {
this._shortList[index] = num;
return;
}
this._doubleList = new double[this._shortList.Length];
for (int i = 0; i < this._shortList.Length; i++) {
this._doubleList[i] = this.ThousandthOfEmToReal(this._shortList[i]);
}
this._doubleList[index] = value;
this._shortList = null;
}
}
干的时把double内部检查范围后存成short的活。也就是说内部其实存的就是short嘛,接口却非要弄个double。 你用户还非得弄个临时集合转一下。干嘛不直接在 GlyphRun就设计个直接接收short的重载呢?提供个重载,应付最典型的数据都是数值较小的数据的情况,这没什么不可以嘛。