Я, честно говоря, не уверен, зачем тратить время на оптимизацию. Вызов этой функции более 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. Но вы должны быть. Вы должны явно установить опцию в свойствах вашего проекта, но преимущества строгой типизации намного перевешивают стоимость прохождения и исправления некоторого существующего кода. Вы можете даже заметить увеличение производительности, особенно если вы случайно использовали много поздних привязок.