首页 > 代码库 > 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(valueout 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的重载呢?提供个重载,应付最典型的数据都是数值较小的数据的情况,这没什么不可以嘛。