Как в мой тип (type) записывать изменяющиеся по размеру массивы / спис

Тема в разделе "Lotus - Программирование", создана пользователем fedotxxl, 22 янв 2008.

  1. fedotxxl

    fedotxxl Well-Known Member

    Регистрация:
    9 ноя 2005
    Сообщения:
    614
    Симпатии:
    0
    Как в мой тип (type) записывать изменяющиеся по размеру массивы / списки?
    Вообще возможно ли это? Если невозможно, то как добиться подобного эффекта другими методами?
     
  2. Yakov

    Yakov Гость

    Используйте класс.
    Смотрите исходники java.util.ArrayList, например.
     
  3. fedotxxl

    fedotxxl Well-Known Member

    Регистрация:
    9 ноя 2005
    Сообщения:
    614
    Симпатии:
    0
    Да, я догадывался, что можно сделать через классы... Но через классы, думаю, сильно медлено будет
     
  4. K-Fire

    K-Fire Гость

    так речь о яве идет или о лотус-скрипте? Если LS то массив/список как вариант объявить и можно будет запихивать любой тип.
     
  5. Yakov

    Yakov Гость

    Речь, конечно же, идет о LotusScript. Я предлагал посмотреть, как реализован класс java.util.ArrayList, и написать подобный класс. Вот мой класс, которым я пользуюсь постоянно.
    Код (Text):
    Private Const CAPACITY_INCREMENT = 512
    Private Const ARRAY_BASE = -32768

    '############################################################################
    ####
    Public Class VariantList

    Private values() As Variant
    Private count As Long
    Private capacity As Long

    Private Sub init()
    capacity = CAPACITY_INCREMENT
    count = 0
    Redim values(0 + ARRAY_BASE To capacity - 1 + ARRAY_BASE)
    End Sub

    Private Sub EnsureCapacity(minCapacity As Long)
    Dim newCapacity As Long
    newCapacity = capacity
    While (newCapacity < minCapacity)
    newCapacity = newCapacity + CAPACITY_INCREMENT
    Wend
    If (capacity < newCapacity) Then
    capacity = newCapacity
    Redim Preserve values(0 + ARRAY_BASE To capacity - 1 + ARRAY_BASE)
    End If
    End Sub

    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ~~~~

    Public Sub New
    Call init()
    End Sub

    Public Sub Delete
    Erase values
    End Sub

    Public Sub add(value As Variant)
    ensureCapacity(count + 1)
    If Isobject(value) Then
    Set values(count + ARRAY_BASE) = value
    Else
    values(count + ARRAY_BASE) = value
    End If
    count = count + 1
    End Sub

    Public Sub clear()
    Erase values
    Call init()
    End Sub

    Public Function getElement(index As Long) As Variant
    If (index >= count) Then Exit Function
    If Isobject(values(index + ARRAY_BASE)) Then
    Set getElement = values(index + ARRAY_BASE)
    Else
    getElement = values(index + ARRAY_BASE)
    End If
    End Function

    Public Function size() As Long
    size = count
    End Function

    End Class
    '############################################################################
    ####
    Ограничения данного класса: количество элементов в коллекции не может превышать 64K. Как это обойти, напишу ниже. Еще одно ограничение - элементы можно только добавлять. У меня еще не было ситуаций, когда из коллекции нужно было удалять элементы. Но реализовать метод remove() не составит труда, я надеюсь. :)
    Далее. Можно написать подкласс данного класса, поддерживающий сортировку элементов. Можно написать класс "суперколлекции" (или "метаколлекции"), который обойдет ограничение вместимости в 64K элементов. Вот пример:
    Код (Text):
    Private Const BLOCK_SIZE = 65536

    Class VariantHugeList

    Private values As VariantList
    Private currentList As VariantList
    Private count As Long
    Private listCount As Long

    Private Sub init()
    count = 0
    listCount = 1
    Set values = New VariantList()
    Set currentList = New VariantList()
    Call values.add(currentList)
    End Sub

    Sub growth()
    listCount = listCount + 1
    Set currentList = New VariantList()
    Call values.add(currentList)
    End Sub

    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ~~~~

    Public Sub New
    Call init()
    End Sub

    Public Sub Delete
    Delete currentList
    Delete values
    End Sub

    Public Sub add(value As Variant)
    If (currentList.size() >= BLOCK_SIZE) Then
    Call growth()
    End If
    count = count + 1
    currentList.add(value)
    End Sub

    Public Sub clear()
    Delete currentList
    Delete values
    Call init()
    End Sub

    Public Function getElement(index As Long) As Variant
    If (index >= count) Then Exit Function
    Dim listIndex As Long
    Dim inListIndex As Long
    Dim varList As Variant
    listIndex = index \ BLOCK_SIZE
    inListIndex = index Mod BLOCK_SIZE
    Set varList = values.getElement(listIndex)
    If Isobject(varList.getElement(inListIndex)) Then
    Set getElement = varList.getElement(inListIndex)
    Else
    getElement = varList.getElement(inListIndex)
    End If
    End Function

    Public Function size() As Integer
    size = count
    End Function

    End Class
    Есть еще "хитрый" динамический массив - список (List):
    Код (Text):
    Dim myList List As Variant
    myList("0") = 0
    myList("1") = 1
    ...
    myList("100000") = 100000
    Про скорость и память напишу ниже, когда "бенчмарк" свой найду.
     
  6. Yakov

    Yakov Гость

    Итак, тесты.
    Участники: обычный массив, VariantList, VariantHugeList, List.
    Тесты: время заполнения коллекции целыми числами, время произвольного доступа (random access) к элементам коллекции, потребление памяти.
    Размеры коллекций - 32K, 64K, 128K элементов.
    Результаты:
    Код (Text):
    32K
    C   RA  M
    Array           0.110   0.015   516
    VariantList  0.328  0.031   516
    VariantHugeList 0.453   0.047   516
    List             0.437  0.047   1688

    64K
    C   RA  M
    Array           0.219   0.031   1028
    VariantList  0.593  0.032   1032
    VariantHugeList 0.719   0.109   1052
    List             1.109  0.141   5340

    128K

    VariantHugeList 1.265   0.203   2064
    List             2.687  0.375   12416
    C - время создания, сек.
    RA - время, портаченное на произвольный доступ к 10% элементов, сек.
    M - потр*цензура*емая коллекцией память, Kb.

    Выводы.
    Выводы делайте сами. :)
     
  7. fedotxxl

    fedotxxl Well-Known Member

    Регистрация:
    9 ноя 2005
    Сообщения:
    614
    Симпатии:
    0
    Для: Yakov
    Можно спросить - каким образом вы проводили тест? Можете выложить свою БД для тестирования?
     
  8. Yakov

    Yakov Гость

    БД выкладывать не стану, покажу тексты.
     

    Вложения:

    • benchmark.zip
      Размер файла:
      2,3 КБ
      Просмотров:
      30
Загрузка...

Поделиться этой страницей