改进异常处理 vb.net
improve the exception handling vb.net
我在异常处理的性能方面遇到了一些小麻烦。
我正在构建...aaaaa...soooo...嗯...图形数据库?是的,像这样的东西...... vb.net。
我正在构建解析器,用于处理 db(?) 的基本功能会发生什么?用户进行研究,程序标记它们,并允许进行一些计算。通常是字符串处理,但是,为了提供一个完整的工具,我还实现了数学函数。
没有办法知道他要插入的开发时数学类型的值。尤其是,无法知道遍历出来的列的每一行是否具有相同的数据类型。它是一个无架构的 db(?)。
那么发生了什么......我必须实施错误处理。
For i As Integer = 0 To pR.r.wsRowCount - 1
Try
pR.r.wsItem(cix, i) = Convert.ToDouble(pR.r.wsItem(ca.ix, i)) * Convert.ToDouble(pR.r.wsItem(cb.ix, i))
Catch
pR.r.wsItem(cix, i) = String.Empty
End Try
Next
像这样...
(psss.. Convert.toDouble()
是 cDbl()
、Double.Parse()
等之间性能最高的函数)。
但是当我 运行 它时,如果所有行(基准大约 2000 行)都是真正的数字...几毫秒,但如果某些行不是数字,则需要 3 或 4 秒。最坏的情况是,如果用户应该在字符串列中进行数学运算……再见,同时最好去喝杯咖啡。
所以我的电脑可能不是世界上最先进的,但你知道是否有任何方法可以避免这种令人难以置信的错误处理延迟?我会记得这是一个查询的解析器,我会避免让它变重。
当您的代码遇到无法转换为双精度值的值时,您正在使用异常解决问题。这称为 使用异常驱动代码 ,这是一种不好的做法。对于这种情况,捕获异常永远不是一个好的解决方案。
特别是当有明确的方法避免它们时
For i As Integer = 0 To pR.r.wsRowCount - 1
Dim d1 As Double
Dim d2 As Double
if Double.TryParse(pR.r.wsItem(ca.ix, i), d1) Then
if Double.TryParse(pR.r.wsItem(cb.ix, i), d2 Then
pR.r.wsItem(cix, i) = (d1 * d2).ToString()
else
pR.r.wsItem(cix, i) = String.Empty
End If
Else
pR.r.wsItem(cix, i) = String.Empty
End If
Next
Convert.ToDouble
无法处理字符串不是有效数值的事实,如果遇到这种情况,则会抛出异常。抛出异常在性能方面代价高昂,特别是对于收集有关调用堆栈的信息。
相反,如果您的输入可能包含无法转换为 double 的值,那么 Double.TryParse
也是正确的方法,如果您的基准测试显示性能略有差异。如果传递的字符串无法转换为双精度数,Double.TryParse
不会引发异常,但 return 为 false。这样就避免了代价高昂的异常,并且您的执行时间更可预测
也就是说,您真的应该重新评估将各种数据存储在某种字符串结构中的方法。字符串和预期数据类型之间不断转换的需要可能是这里真正的瓶颈。
我在异常处理的性能方面遇到了一些小麻烦。
我正在构建...aaaaa...soooo...嗯...图形数据库?是的,像这样的东西...... vb.net。
我正在构建解析器,用于处理 db(?) 的基本功能会发生什么?用户进行研究,程序标记它们,并允许进行一些计算。通常是字符串处理,但是,为了提供一个完整的工具,我还实现了数学函数。
没有办法知道他要插入的开发时数学类型的值。尤其是,无法知道遍历出来的列的每一行是否具有相同的数据类型。它是一个无架构的 db(?)。
那么发生了什么......我必须实施错误处理。
For i As Integer = 0 To pR.r.wsRowCount - 1
Try
pR.r.wsItem(cix, i) = Convert.ToDouble(pR.r.wsItem(ca.ix, i)) * Convert.ToDouble(pR.r.wsItem(cb.ix, i))
Catch
pR.r.wsItem(cix, i) = String.Empty
End Try
Next
像这样...
(psss.. Convert.toDouble()
是 cDbl()
、Double.Parse()
等之间性能最高的函数)。
但是当我 运行 它时,如果所有行(基准大约 2000 行)都是真正的数字...几毫秒,但如果某些行不是数字,则需要 3 或 4 秒。最坏的情况是,如果用户应该在字符串列中进行数学运算……再见,同时最好去喝杯咖啡。
所以我的电脑可能不是世界上最先进的,但你知道是否有任何方法可以避免这种令人难以置信的错误处理延迟?我会记得这是一个查询的解析器,我会避免让它变重。
当您的代码遇到无法转换为双精度值的值时,您正在使用异常解决问题。这称为 使用异常驱动代码 ,这是一种不好的做法。对于这种情况,捕获异常永远不是一个好的解决方案。
特别是当有明确的方法避免它们时
For i As Integer = 0 To pR.r.wsRowCount - 1
Dim d1 As Double
Dim d2 As Double
if Double.TryParse(pR.r.wsItem(ca.ix, i), d1) Then
if Double.TryParse(pR.r.wsItem(cb.ix, i), d2 Then
pR.r.wsItem(cix, i) = (d1 * d2).ToString()
else
pR.r.wsItem(cix, i) = String.Empty
End If
Else
pR.r.wsItem(cix, i) = String.Empty
End If
Next
Convert.ToDouble
无法处理字符串不是有效数值的事实,如果遇到这种情况,则会抛出异常。抛出异常在性能方面代价高昂,特别是对于收集有关调用堆栈的信息。
相反,如果您的输入可能包含无法转换为 double 的值,那么 Double.TryParse
也是正确的方法,如果您的基准测试显示性能略有差异。如果传递的字符串无法转换为双精度数,Double.TryParse
不会引发异常,但 return 为 false。这样就避免了代价高昂的异常,并且您的执行时间更可预测
也就是说,您真的应该重新评估将各种数据存储在某种字符串结构中的方法。字符串和预期数据类型之间不断转换的需要可能是这里真正的瓶颈。