有什么办法让这个LINQ更快?

Mal*_*ist 2 c# linq custom-controls .net-3.5

我有一个LINQ表达式,正在减慢我的应用程序.我正在绘制一个控件,但为了做到这一点,我需要知道将出现在我的列中的文本的最大宽度.

我这样做的方式是这样的:

return Items.Max(w => TextRenderer.MeasureText((w.RenatlUnit == null)? "" : 
w.RenatlUnit.UnitNumber, this.Font).Width) + 2;
Run Code Online (Sandbox Code Playgroud)

但是,这会迭代大约1000个项目,并占用我绘图方法中使用的CPU时间的大约20%.更糟糕的是,还有两个必须完成的列,因此所有项/列上的LINQ语句占用了大约75-85%的CPU时间.

TextRenderer来自System.Windows.Forms包,因为我没有使用等宽字体,所以需要使用MeasureText来计算字符串的像素宽度.

我怎么能让这更快?

Ada*_*son 6

我不相信你的问题在于LINQ的速度,它在于你的呼叫MeasureText超过1000次.我认为从LINQ查询中取出逻辑并将其置于普通foreach循环中会产生类似的运行时间.

一个更好的想法可能是采用一点点理智来检查你正在做什么.如果您使用合理的输入(并忽略换行的可能性),那么您实际上只需要测量字符串的文本,例如,在绝对最长(以字符数表示)字符串的10%左右,字符串,然后使用最大值.换句话说,如果最大值是"古生物学",则测量字符串"foo"没有意义.没有字体宽度可变.


Guf*_*ffa 6

MeasureText是需要时间的方法,因此提高速度的唯一方法是减少工作量.

您可以将调用的结果缓存到MeasureText字典中,这样您就不必重新测量之前已经测量过的字符串.

您可以计算一次值,并与要显示的数据保持一致.无论何时更改数据,都会重新计算值.这样,每次绘制控件时都不必测量字符串.