Я часто вижу вопросы коснуться Overflow
ошибки с vba.
Мой вопрос состоит в том почему использование integer
объявление переменной вместо того, чтобы просто определить все числовые переменные (исключая double
и т.д.) как long
?
Если Вы не выполняете операцию как в для цикла, где можно гарантировать, что значение не превысит эти 32 767 пределов, есть ли влияние на производительность или что-то еще, что продиктовало бы не использование long
?
Я взял метод @PGSystemTester и обновил его для удаления некоторой потенциальной изменчивости. Путем размещения цикла в стандартные программы это удаляет время, потраченное для вызова стандартной программы (который является большим количеством времени). Я также выключил экранное обновление для удаления любых задержек, которые это может вызвать.
Long
все еще выполнил лучшее, и поскольку эти результаты более тесно ограничены влиянием одних только тип переменных, величину изменения стоит отметить.
Мои результаты (рабочий стол, Windows 7, Excel 2010):
Код использовал:
Option Explicit
Sub VariableOlympics()
'Run this macro as many times as you'd like, with an activesheet ready for data
'in cells B2 to D6
Dim beginTIME As Double, trials As Long, i As Long, p As Long
Dim chosenWorksheet As Worksheet
Set chosenWorksheet = ThisWorkbook.Sheets("TimeTrialInfo")
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
trials = 1000000000 ' 1,000,000,000 - not 10,000,000,000 as used by @PGSystemTester
p = 0
beginTIME = Now
boomBYTE trials
Finished p, Now - beginTIME, CDbl(trials), chosenWorksheet.Range("B2")
p = p + 1
beginTIME = Now
boomINTEGER trials
Finished p, Now - beginTIME, CDbl(trials), chosenWorksheet.Range("B2")
p = p + 1
beginTIME = Now
boomLONG trials
Finished p, Now - beginTIME, CDbl(trials), chosenWorksheet.Range("B2")
p = p + 1
beginTIME = Now
boomDOUBLE trials
Finished p, Now - beginTIME, CDbl(trials), chosenWorksheet.Range("B2")
p = p + 1
beginTIME = Now
boomUNDECLARED trials
Finished p, Now - beginTIME, CDbl(trials), chosenWorksheet.Range("B2")
p = p + 1
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
chosenWorksheet.Calculate
End Sub
Private Sub boomBYTE(numTrials As Long)
Dim a As Byte, b As Byte, c As Byte
Dim i As Long
For i = 1 To numTrials
a = 1
b = 1 + a
c = 1 + b
c = c + 1
Next i
End Sub
Private Sub boomINTEGER(numTrials As Long)
Dim a As Integer, b As Integer, c As Integer
Dim i As Long
For i = 1 To numTrials
a = 1
b = 1 + a
c = 1 + b
c = c + 1
Next i
End Sub
Private Sub boomLONG(numTrials As Long)
Dim a As Long, b As Long, c As Long
Dim i As Long
For i = 1 To numTrials
a = 1
b = 1 + a
c = 1 + b
c = c + 1
Next i
End Sub
Private Sub boomDOUBLE(numTrials As Long)
Dim a As Double, b As Double, c As Double
Dim i As Long
For i = 1 To numTrials
a = 1
b = 1 + a
c = 1 + b
c = c + 1
Next i
End Sub
Private Sub boomUNDECLARED(numTrials As Long)
Dim a As Variant, b As Variant, c As Variant
Dim i As Long
For i = 1 To numTrials
a = 1
b = 1 + a
c = 1 + b
c = c + 1
Next i
End Sub
Private Sub Finished(i As Long, timeUSED As Double, trials As Double, initialCell As Range)
With initialCell.Offset(i, 0)
.Value = trials
.Offset(0, 1).Value = timeUSED
.Offset(0, 2).FormulaR1C1 = "=ROUND(RC[-1]*3600*24,2)"
End With
End Sub
Как другие уже упомянули, , Long может занимать вдвое больше места как Целое число . Как другие также уже упомянули, большая емкость данных компьютеров означает, что Вы будете видеть никакая разница в производительности безотносительно , если Вы не будете иметь дело с дополнительными дополнительными очень большими объемами данных:
Рассмотрение 1 миллион значений , различие между использованием Целых чисел по сравнению с Longs имело бы 2 байта для каждого значения, так, чтобы был 2 * 1 000 000 / 1,024 / 1024 = меньше чем 2 МБ различия в Вашем RAM, который является, вероятно, намного меньше чем 1% или даже 0,1% Вашей способности RAM.
Рассмотрение сравнительного теста, сделанного PGSystemTester, Вы видите различие 811 - 745 = 66 секунд между Longs и Integers при обработке 10 миллиардов пакетов 4 операций каждый. Сократите количество к [1 113] 1 миллион операций , и мы можем ожидать 66 / 10 000 / 4 = меньше чем 2 мс различия во время выполнения .
<час>я лично использую Integers и Longs к [1 115] удобочитаемость справки моего кода , особенно в циклах, где Целое число указывает, что цикл, как ожидают, будет маленьким (меньше чем 1 000 повторений), тогда как Long говорит мне, что цикл, как ожидают, будет довольно большим (больше чем 1 000).
Примечание этот субъективный порог значительно ниже Целочисленного верхнего предела, я использую Longs только для создания различия между моими собственными определениями маленьких и больших.