这可能是一个愚蠢的问题,但我对使用try / catch块的性能感兴趣。
我有一个DataGrid,它将Converter分配给DataGridCell的background属性。在转换器中,我将今年数据的值与去年的数据进行比较;如果今年的数据是> 3%,我回归绿色背景;如果它是> 0%和< 3%,我返回黄色;如果它是< 0%,我回红:
string x = values[0].ToString().Replace("$", "").Replace(",", ""); //This year's number
string y = values[1].ToString().Replace("$", "").Replace(",", ""); //Last year's
result = (((float.Parse(x) * 100) / float.Parse(y)) - 1) * 100;
if (result >= 3)
return Brushes.LimeGreen;
else if (result >= 0)
return Brushes.Yellow;
else
return Brushes.Red;
然而,在某些情况下,该单元格的价值不会超过去年;你可以猜到,除以0(或者当Cell为空时转换器似乎收到的一些文本)是一个非常糟糕的主意,并会引发异常。所以,我决定解决这个问题的最简单方法是:
try
{
result = (((float.Parse(x) * 100) / float.Parse(y)) - 1) * 100;
}
catch
{
return Brushes.DarkOrange;
}
因此,如果抛出异常(由此没有可比较的值),返回橙色并将其称为一天。 (编辑:是的,我确实希望在没有可比较的值时返回橙色。
目前,我可以预测它现在只会发生在一行数据中,所以它只会在填充时捕获大约10个单元格。但随着未来的发展,它有可能让它发生更多次。
try / catch块是处理这个问题的最简单快捷的方法(据我所知),但这显然不是唯一的方法,特别是因为我知道错误。那么在这种情况下使用try / catch块是个坏主意吗?而且糟糕的是,我的意思是它会降低性能,因为它经过多次,多次迭代?鉴于我知道错误是什么,我应该先抢占它,还是使用try / catch块?
答案 0 :(得分:10)
这是一个坏主意。这不是一个特例,所以不要像它那样处理它。你担心性能和异常处理的事实是你做错了什么的气味。有一种非常简单的方法来处理这个问题,所以我甚至不知道为什么你会想到使用异常处理来处理它。
是的,它会影响您的表现,但这不应该是您的关注点。你应该关注编写这种逻辑的最清晰的方法,而使用异常显然不是这样。
这是一个简单的方法:
double value;
if(!Float.TryParse(y, out value) || value == 0f) {
return Brushes.DarkOrange;
}
else {
double result = (((float.Parse(x) * 100) / value) - 1) * 100;
if (result >= 3) {
return Brushes.LimeGreen;
}
else if (result >= 0) {
return Brushes.Yellow;
}
else {
return Brushes.Red;
}
}
答案 1 :(得分:7)
一般而言,例外情况应该用于真正例外情况 - 不期望的情况。在这种情况下,如果你很清楚上一年可能没有,我建议使用简单的if()
检查来返回你的默认值。
要回答您的效果问题,Microsoft says表示"抛出异常会对性能产生负面影响"。
答案 2 :(得分:3)
try catch是.Net框架上性能最差的一个。查看here当引发异常时,必须检查堆栈跟踪以查找该特定异常的捕获方法,这是一项代价高昂的操作。
如果你考虑到表现,就不要做那种例外的事情(即使你没有考虑到表现,我也会说。)
答案 3 :(得分:2)
Catch语句只应用于捕获异常。不改变程序流程。所以回答你的问题,是的,这是一个坏主意。 我无法想象它是高性能的,因为将创建一个新的Exception对象,并且很可能java会对事件进行一些记录,所以最好只使用if语句。
答案 4 :(得分:2)
以你在问题中描述的方式使用catch块是一个坏主意。 Try-catch块本身不会对性能产生巨大影响,但异常确实会产生很大的性能成本。
最好的选择是在float类上使用TryParse
方法。它存在的原因。
答案 5 :(得分:2)
答案 6 :(得分:1)
我对c#的复杂性不太熟悉,告诉你if,或tryparse语句或try catch是否会更快。我能为您提供的是思考电话的想法。
如果您担心某项操作的性能与执行相同过程一样简单,请考虑调用次数。如果检查每个数字是否为0,或者对每个数字调用try-parse,那么您将对每次迭代添加该调用,而不仅仅是失败的迭代。如果这个实现适合你,这是一个很好的方法,因为它只有在失败时进入catch块。
对于许多程序,这种实现方式不起作用,因为它们希望在catch块中进行额外的处理。对于那些程序,您需要检查0,或者执行tryparse。由于您刚回来,我相信这会使代码易于阅读。