好的,这段代码有效,但我认为中间有一些必要的步骤可以达到目的。有关如何使其更紧的任何想法?
Public Function CalCheckSum(ByVal ByteList As List(Of Byte)) As List(Of Byte)
Dim total As Integer = 0
For Each b As Byte In ByteList
total = total + b
Next
Dim modedVal As Integer = 0
modedVal = total Mod &H100
Dim negatedValue As Integer = 0
negatedValue = &H100 - modedVal
Dim charList As List(Of Char) = Hex(negatedValue).ToCharArray.ToList
Dim returnList As New List(Of Byte)
For Each ch As Char In charList
returnList.Add(Asc(ch))
Next
Return returnList
End Function
BTW这就是我用来测试它的方法:
Dim blist As New List(Of Byte)
blist.Add(&H52)
blist.Add(&H34)
blist.Add(&H35)
blist.Add(&H31)
blist.Add(&H32)
blist.Add(&H33)
blist.Add(&H34)
blist.Add(&H30)
blist.Add(&H30)
blist.Add(&H30)
blist.Add(&H30)
blist.Add(&H46)
blist.Add(&H46)
blist.Add(&H46)
blist.Add(&H46)
blist.Add(&H42)
blist.Add(&H4B)
blist.Add(&H9)
blist.Add(&H44)
Dim b As List(Of Byte) = CalCheckSum(blist)
b
的正确值为:
b(0)
=& H43 b(1)
=& H39 答案 0 :(得分:2)
老实说,我不确定为什么要浪费时间来优化它。在循环中调用该函数超过100,000次需要小于20毫秒。即使这是您应用程序中的“热点”之一(因为您说它与嵌入式硬件设备通信),通过优化您的代码,您不太可能看到任何明显的速度提升。
但只是为了好玩,我决定看看我是不是可以稍微优化一下......这就是我想出的:
删除多余的List(Of Char)
创建。您已经使用ToCharArray
方法将值转换为数组。为什么要花费ToList
来调用它,只是为了迭代它?您也可以通过数组进行迭代。这样可以将时间减少到大约8秒,这是一个非常大的速度,只需很少的努力。
您还可以将新List(Of Byte)
的大致大小作为参数传递给构造函数。您已经从charArray
的大小知道了这一点,因为您只是将这些元素添加回来。当您只使用两个项目时,这没有任何区别,例如您提供,但它可以使更大的元素数量更有效,因为List
不必在循环期间的任何点动态调整大小。
Asc
,AscW
和Convert.ToInt32
之间绝对没有区别。我明确地测量了它们中的每一个。我的直觉是将其改为AscW
,但显然无所谓。很多人会因使用特定于VB的习语而嗤之以鼻,并推荐他们认为.NET Framework提供的更通用的方法。事实证明,由于所有特定于VB的代码都是在与备选方案相同的托管代码中编写的,因此您可以使用它来简单地优先考虑。
否则用简单数组替换List(Of T)
也不会产生任何明显的差异。由于List
更容易在函数外部使用,因此您可以将其保留为返回的类型。
所以我的最终代码看起来像这样:
Public Function CalCheckSum(ByVal ByteList As List(Of Byte)) As List(Of Byte)
Dim total As Integer = 0
For Each b As Byte In ByteList
total = total + b
Next
Dim negatedValue As Integer = 0
negatedValue = &H100 - (total Mod &H100)
Dim charArray As Char() = Hex(negatedValue).ToCharArray()
Dim returnList As New List(Of Byte)(charArray.Length)
For Each ch As Char In charArray
returnList.Add(CByte(Asc(ch)))
Next
Return returnList
End Function
即使在循环中运行这999,000次,我也一直在62到64毫秒之间调整时间。
您也可以使用 LINQ 。这不是我的区域,我怀疑你会看到任何可测量的速度增加(它仍然需要进行相同数量的循环和迭代)。它提供的最大好处是您的代码更简单,看起来更干净。我很惊讶有人还没有发布这个解决方案。
编辑:顺便说一下,你的原始代码没有为我编译。我必须添加CByte
运算符,才能将Integer
运算符返回的Asc
值转换为Byte
类型。这告诉我你没有使用 Option Strict On进行编程。 但你应该是。你必须在项目的属性中明确设置选项,但强类型的好处远远超过了完成和修复现有代码的成本。您甚至可能会注意到性能提升,特别是如果您无意中使用了大量后期绑定。