Какой тип переменной будет лучше для массива? - PullRequest
0 голосов
/ 03 июня 2018

В настоящее время я объявляю multiple arrays, более 25, которые содержат числа и пробелы, типа Variant.Я понимаю, что Variant может сильно замедлить макрос. Вопрос : является ли Variant правильным выбором, или другой тип будет лучше?Пример кода ниже ...

Dim RM1() As Variant
RM1() = Array("64", "65", " ", "66", "67", " ", "68", "69", " ", _
        "70", "71", " ", "72", "73", " ", "74", "75", " ", "76", _
        " ", "77", "", "78", " ", "79", " ")

Dim RM2() As Variant
RM2() = Array("20", " ", " ", "21")

и т. Д.и т.д.

1 Ответ

0 голосов
/ 04 июня 2018

Тип данных переменной должен быть Variant, чтобы использовать ее с функцией Array.


Функция массива

Синтаксис: Array ( arglist )

Возвращает Variant, содержащиймассив.

Обязательный аргумент arglist - это список значений, разделенных запятыми, которые присваиваются элементам массива, содержащимся в Вариант .

ПРИМЕЧАНИЕ: a Вариант , который не объявлен как массив, все еще может содержатьмассив.Переменная Variant может содержать массив любого типа, , кроме строк фиксированной длины и пользовательских типов. Хотя Вариант , содержащий массив, концептуально отличается отмассив, элементы которого имеют тип вариант , доступ к элементам массива осуществляется аналогичным образом.

( источник )


На скорость обработки влияет тип данных массива?

Я проверил вашу теорию о том, что скорость операций На влияет тип данных массива .

В вашем примере есть только один тип данных, кроме Variant, который можно использовать (String), так как ваш массивудерживайте числа и пробелы.


Сводка результатов:

Числовой (5 миллионов циклов) **

Integer()   1.08 sec   20% faster than Variant             
Long()      1.09 sec                                       
Single()    1.29 sec                                       
Variant()   1.34 sec                                       
Double()    1.37 sec   

Числовой (25 миллионов циклов) **

Variant()   6.16 sec   Variant is 9% faster than String    
String()    6.76 sec                                       

Числа хранятся в виде текста (5 миллионов циклов) **

Integer()   5.45 sec   Variant is 32% faster than Integer  
Variant()   7.99 sec                                       

Следовательно, , это правда: массивы невариантных типов данных обрабатываются на 20% быстрее , чем Array of Variants.Однако в этом случае это означает, что 0.6 seconds были сохранены при 2 миллиардах взаимодействиях с массивами.


Использование GMalc's пример данных :

Важно отметить: в случае данных примера OP: Сохранение чисел в виде строк (например, данных примера) - ваша реальная проблема, , увеличивая в шесть раз , чем при использованиичисловой тип данных.


Подробные результаты теста и код:

Время выполнения используя строки из четырех цифр:

    Type       #1     #2     #3     #4     #5   
 ----------- ------ ------ ------ ------ ------ 
  Variant()   6.18   6.15   6.15   6.14   6.12 seconds
  Variant()    6.2    6.2   6.21   6.18   6.19  
  Variant()   6.22   6.18   6.16   6.19   6.19  
  Variant()   6.14   6.11   6.12   6.11   6.14  
  String()    7.09   6.79   7.12   6.73   6.77  
  String()    6.87   6.72   6.77    6.7   6.68  
  String()     6.7   6.69    6.7   6.69    6.7  
  String()     6.7   6.68   6.68   6.71   6.69  

время выполнения с использованием 4-значных чисел:

  Integer()   1.09   1.07   1.08   1.08   1.09 seconds
  Integer()   1.07   1.09   1.08   1.07   1.08  
  Integer()   1.08   1.07   1.08   1.08   1.09  
  Integer()   1.09   1.08   1.07   1.08   1.09  
  Long()      1.08   1.08   1.09   1.08   1.08  
  Long()      1.09   1.08   1.08   1.09   1.08  
  Long()      1.09   1.08    1.2   1.09   1.08  
  Long()      1.09   1.09   1.09   1.09   1.09  
  Single()    1.29    1.3   1.29   1.29   1.29  
  Single()    1.29   1.29   1.29   1.28   1.28  
  Single()    1.29   1.28   1.29   1.29   1.28  
  Single()    1.29   1.27    1.3   1.29   1.29  
  Double()    1.28   1.27   1.29    1.3   1.34  
  Double()    1.34   1.34   1.52   1.76   1.43  
  Double()     1.3   1.33    1.4    1.3   1.35  
  Double()    1.38   1.41   1.38    1.4   1.33  
  Variant()   1.33   1.34   1.32   1.34   1.32  
  Variant()   1.32   1.34   1.32   1.33   1.32  
  Variant()   1.34   1.34   1.34   1.42   1.31  
  Variant()   1.35   1.39   1.33   1.38   1.38  

Время выполнения для варианта / целого числа, 4-значные числа:

  Variant()   6.61   6.59   6.59   6.59    6.6 seconds
  Variant()   8.36   8.88   8.29   8.17   8.18  
  Variant()   9.13   9.41   8.59   8.25   8.27  
  Variant()   8.25   8.17   8.16   8.38   8.29  
  Integer()   5.45   5.45   5.43   5.44   5.45  
  Integer()   5.45   5.44   5.44   5.45   5.45  
  Integer()   5.44   5.44   5.45   5.45   5.45  
  Integer()   5.44   5.45   5.46   5.45   5.45  

Метод тестирования:

  • 5 миллионов циклов на # тест, каждый из которых "взаимодействует" с массивом4 раза, умноженные на 5x4 процессов
    = 400 миллионов"взаимодействий" wi-й массив для каждого типа данных

  • 25 миллионов циклов на # тест, каждый из которых "взаимодействует" с массивом 4 раза, умноженный на процессы 5x4
    = 2 миллиарда"взаимодействий" с массивом


Код тестирования:

Ниже приведен код, который я собрал вместе для теста:

Option Explicit
Const loops = 25000000
Public arr1(1 To loops) As Integer, arr2(1 To loops) As Integer, el

Sub runTests()
    Dim t As Long
    Debug.Print TypeName(arr1) & " (" & loops & " loops): ";
    For t = 1 To 5
        Debug.Print "#" & t & ": " & Format(testArray, "0.00") & "sec, ";
        DoEvents
    Next t
    Debug.Print "Done."
End Sub

Function testArray() As Double
'are arrays faster to use when data type is non-variant?
'I consider this procedure to be "touching" the arrays a "total of (4 * [Loops]) times"
    Dim x As Long, startTime As Single: startTime = Timer
    For x = 1 To loops 'populate arr1 with 4-digit numeric strings
        arr1(x) = IIf(TypeName(arr2) = "String", CStr(Int((Rnd() * 11000) + 1001)), Int((Rnd() * 11000) + 1001))
    Next x

    For x = LBound(arr1) To UBound(arr1) 'copy arr1 to arr2, one element at a time
        arr2(x) = arr1(x)
    Next x

    For Each el In arr2 'iterate & clear arr2
        If el = IIf(TypeName(arr2) = "String", "99999", 99999) Then '(won't be found)
            Debug.Print "Found!"
            Exit For
        End If
        el = Null
    Next el
    testArray = (Timer - startTime)
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...