Не подведет ли Collection???

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
newonline
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 115
Зарегистрирован: 13.08.2005 (Сб) 14:50
Откуда: Воронеж

Не подведет ли Collection???

Сообщение newonline » 30.08.2005 (Вт) 18:48

Вопрос вот о чем:
:o Для сохранения, записи и чтения переменных в своей проге задействовал Collection. Здесь: Key - имя переменной, Item - значение переменной. Большую часть цикла обработки данных Collection будет работать с ключами, и лишь небольшую часть времени по конструкции For Each item in Collection....
Насколько может снизиться производительность обработки данных, когда число переменных приблизится к 150 (200) тыс.?
И есть ли другой вариант лучшей производительности? :roll:
Оно конечно да, ежели что как...а то ведь как получится, так вот вам и пожалуйста...

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 30.08.2005 (Вт) 18:50

Эм... А чем массив не угодил?
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 30.08.2005 (Вт) 19:02

Необходимостью ручного смещения всех элементов после удаления одного или нескольких. Отсутствием быстрого и наглядного доступа по ключу (только прямой перебор вариантов). И т.д...

Кстати, именно эффективная работа с ключами и поддержка For Each... - преимущества коллекций. :D
Моду создают модоки, а распространяют модозвоны.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 30.08.2005 (Вт) 19:23

hCORe писал(а):Кстати, именно эффективная работа с ключами и поддержка For Each... - преимущества коллекций. :D

Перед чем? :-?
Изображение

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 30.08.2005 (Вт) 19:27

Перед массивами. Я не спорю, что можно создать класс для хранения данных на основе массивов, реализующий IENUMVariant, и получить тот же самый for each.

Но коллекция - это встроенный тип данных. Притом - не самый плохой.

Если ему нужна скорость операций - пусть выбирает двумерный массив.
Если ему нужно удобство перебора и выборки по ключу - нужна коллекция.
Если нужно быстро удалить один элемент, не затрудняя себя ресайзом массива - нужна коллекция.

Я прав?
Моду создают модоки, а распространяют модозвоны.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 30.08.2005 (Вт) 19:48

hCORe писал(а):Перед массивами.
...
Я прав?

Нет.
Код: Выделить всё
Dim v
For Each v In Array("А", "ты", "знал,", "что", "такое", "возможно?")
    Debug.Print v; " ";
Next
Изображение

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 30.08.2005 (Вт) 19:58

Да. Но это массив типа Variant. Что уже изначально не есть хорошо.
Тем более, коллекции чуть-чуть более наглядны, чем массивы... И более оптимизированы, чем массивы типа Variant.
Моду создают модоки, а распространяют модозвоны.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 30.08.2005 (Вт) 20:26

hCORe писал(а):Да. Но это массив типа Variant. Что уже изначально не есть хорошо.
Тем более, коллекции чуть-чуть более наглядны, чем массивы... И более оптимизированы, чем массивы типа Variant.

Тип массива не имеет никакого отношения к поддержке For Each.
Код: Выделить всё
Dim v, foo(5) As Long
foo(1) = 5: foo(2) = 3: foo(3) = 4: foo(4) = 2: foo(5) = 1
For Each v In foo
    Debug.Print v;
Next
Изображение

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 30.08.2005 (Вт) 20:36

Хе-хе. hCORe - удивись :)

Код: Выделить всё
Option Explicit

Private Declare Function GetTickCount Lib "kernel32" () As Long

Dim lCurTime As Long

Private Sub cmdArr_Click()
    lCurTime = GetTickCount()

    Dim i As Variant
    Dim myArr(512) As Variant
    For i = LBound(myArr) To UBound(myArr)
        myArr(i) = Int(100000 * Rnd)
    Next i
    For Each i In myArr
        Debug.Print i
    Next i
   
    txtArr.Text = "result: " & GetTickCount - lCurTime
End Sub

Private Sub cmdColl_Click()
    lCurTime = GetTickCount()

    Dim i As Variant
    Dim myColl As New Collection
    For i = 0 To 512
        myColl.Add Int(100000 * Rnd), "Var" & i
    Next i
    For Each i In myColl
        Debug.Print i
    Next i
   
    txtColl.Text = "result: " & GetTickCount - lCurTime
End Sub
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

newonline
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 115
Зарегистрирован: 13.08.2005 (Сб) 14:50
Откуда: Воронеж

Сообщение newonline » 30.08.2005 (Вт) 20:45

hCORe писал(а):
Если ему нужна скорость операций - пусть выбирает двумерный массив.



Что, найти Znachenie = MyVariableCollection.Item ("VarName")
вовсе не быстрее:

for i =1 to UBound(MyVarArray)
if MyVarArray(0)="VarName" then
Znachenie = MyVarArray(1)
Exit Sub
End if

Если при этом искомый элемент на 198542 месте??? :?


hCORe писал(а):
Но коллекция - это встроенный тип данных. Притом - не самый плохой.



А что есть еще лучше?
Оно конечно да, ежели что как...а то ведь как получится, так вот вам и пожалуйста...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 30.08.2005 (Вт) 20:46

BV, несчитово. Добавь поиск по ключу и удаление из середины.
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 30.08.2005 (Вт) 20:49

newonline, вместо того чтобы строить догадки - напиши два теста, с теми действиями, которые твоя прога будет выполнять: один с коллекцией, другой с массивом. Запусти и сравни время. И не нужно будет никому тебя ни в чём убеждать - ты сам всё увидишь.
Изображение

newonline
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 115
Зарегистрирован: 13.08.2005 (Сб) 14:50
Откуда: Воронеж

Сообщение newonline » 30.08.2005 (Вт) 20:53

Я просто хотел сэкономить время не только на работе массива или коллекции, но и на сравнении скоростей, которое уже кто-то, наверняка, делал. Вот. :)
Оно конечно да, ежели что как...а то ведь как получится, так вот вам и пожалуйста...

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 30.08.2005 (Вт) 21:01

На моем компе результат одинаковый - 266 мс. Зато быстро удалить из массива в 1 млрд. ячеек триста тысяч значений в разных местах и уничтожить пустоты - довольно сложная и долгая задача :lol:
Моду создают модоки, а распространяют модозвоны.

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 30.08.2005 (Вт) 21:19

Ну, с коллекцией просто, например, так:

Код: Выделить всё
    For i = 0 To 512
        If myColl.Item("Var" & i) > 50000 And myColl.Item("Var" & i) < 80000 Then
            myColl.Remove ("Var" & i)
        End If
    Next i


С массивом, понятно, сложнее, но: http://vbstreets.ru/VB/Articles/66160.aspx

Не знаю, но у меня при работе без удаления массив выигрывает.
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

newonline
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 115
Зарегистрирован: 13.08.2005 (Сб) 14:50
Откуда: Воронеж

Сообщение newonline » 30.08.2005 (Вт) 21:44

Э-э... Спасибо.... Запутали окончательно.... :roll:
Оно конечно да, ежели что как...а то ведь как получится, так вот вам и пожалуйста...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 30.08.2005 (Вт) 21:48

hCORe, ты как-то избежал ответа: признаёшь, что нижеотквоченное - гон?

hCORe писал(а):Перед массивами. Я не спорю, что можно создать класс для хранения данных на основе массивов, реализующий IENUMVariant, и получить тот же самый for each.
Изображение

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 31.08.2005 (Ср) 9:02

Все равно у коллекции есть преимущества перед массивами. Ты, между прочим, их сам назвал: быстрый поиск по ключу, удаление элементов из произвольных мест. Про for each - не знал. Спасибо, что просветил :)
Моду создают модоки, а распространяют модозвоны.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 31.08.2005 (Ср) 9:06

hCORe писал(а):Все равно у коллекции есть преимущества перед массивами.

Также как и у массивов перед коллекциями.
А при наличии желания, массивы можно индексировать и реализовать быстрый поиск. Если требуется частое удаление-вставка элементов, то на базе массивов можно сделать цепочки (списки).
Lasciate ogni speranza, voi ch'entrate.

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 31.08.2005 (Ср) 10:13

Именно: при наличии желания, возможностей, опыта. Можно и списки сделать (как в рекламе: "Моожно и в кооосмосс - просто мы... не торопимся!"). В зависимости от конкретной задачи, решение может быть разным: простой двумерный массив, коллекция, расширенная структура данных на основе массивов. И что будет быстрее - во многом зависит от спектра выполняемых задач. Естественно, можно индексировать массивы. Только зачем? Если коллекция обеспечивает приемлемое быстродействие при выборке по ключу?..
Моду создают модоки, а распространяют модозвоны.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 31.08.2005 (Ср) 10:16

Попробуй у элемента встроенной коллекции узнать индекс или ключ?
Lasciate ogni speranza, voi ch'entrate.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 31.08.2005 (Ср) 11:17

hCORe писал(а):В зависимости от конкретной задачи, решение может быть разным: простой двумерный массив, коллекция, расширенная структура данных на основе массивов. И что будет быстрее - во многом зависит от спектра выполняемых задач. Естественно, можно индексировать массивы. Только зачем? Если коллекция обеспечивает приемлемое быстродействие при выборке по ключу?..

Для задачи "быстрый поиск по индексу и ключу" не подходит ни обычный массив, ни обычная коллекция. Вот тебе пример, когда приходится писать что-то своё. Я писал, работало по скорости с ключами - как стандартная коллекция, с индексами - как стандартный массив :-)
Но там, естественно, тормозило добавление в середину и удаление из середины. Потому что в той задаче коллекция только росла и только в конец, и меня это устраивало.

Просто нельзя, как тут все подбивают, выяснять - что лучше "вообще", массивы или коллекции. Когда-то одно, когда-то другое, когда-то ни то ни другое не подходит.
Изображение

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 31.08.2005 (Ср) 11:53

Есть и такие задачи :)

Но, поскольку задавший вопрос говорит, что
newonline писал(а):Большую часть цикла обработки данных Collection будет работать с ключами

то MSDN рекомендует:

Visual Basic Concepts. Optimizing Code.

< ... >

Take Advantage of Collections
The ability to define and use collections of objects is a powerful feature of Visual Basic. While collections can be very useful, for the best performance you need to use them correctly:

Use For Each...Next rather than For...Next.

Avoid using Before and After arguments when adding objects to a collection.

Use keyed collections rather than arrays for groups of objects of the same type.
Collections allow you to iterate through them using an integer For...Next loop. However, the For Each...Next construct is more readable and in many cases faster. The For Each...Next iteration is implemented by the creator of the collection, so the actual speed will vary from one collection object to the next. However, For Each...Next will rarely be slower than For...Next because the simplest implementation is a linear For...Next style iteration. In some cases the implementor may use a more sophisticated implementation than linear iteration, so For Each...Next can be much faster.

It is quicker to add objects to a collection if you don't use the Before and After arguments. Those arguments require Visual Basic to find another object in the collection before it can add the new object.

When you have a group of objects of the same type, you can usually choose to manage them in a collection or an array (if they are of differing types, a collection is your only choice). From a speed standpoint, which approach you should choose depends on how you plan to access the objects. If you can associate a unique key with each object, then a collection is the fastest choice. Using a key to retrieve an object from a collection is faster than traversing an array sequentially. However, if you do not have keys and therefore will always have to traverse the objects, an array is the better choice. Arrays are faster to traverse sequentially than collections.

For small numbers of objects, arrays use less memory and can often be searched more quickly. The actual number where collections become more efficient than arrays is around 100 objects; however, this can vary depending on processor speed and available memory.

For More Information See "Using Collections as an Alternative to Arrays" in "More About Programming."
Моду создают модоки, а распространяют модозвоны.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 31.08.2005 (Ср) 12:17

hCORe писал(а):
From a speed standpoint, which approach you should choose depends on how you plan to access the objects. If you can associate a unique key with each object, then a collection is the fastest choice. Using a key to retrieve an object from a collection is faster than traversing an array sequentially. However, if you do not have keys and therefore will always have to traverse the objects, an array is the better choice. Arrays are faster to traverse sequentially than collections.

А тут как раз не рассмотрен мой вариант "есть ключи, но не у всех элементов, и нужен доступ и по ключам и по индексам" :-P
Последний раз редактировалось tyomitch 31.08.2005 (Ср) 12:22, всего редактировалось 1 раз.
Изображение

hCORe
VB - Экстремал
VB - Экстремал
Аватара пользователя
 
Сообщения: 2332
Зарегистрирован: 22.02.2003 (Сб) 15:21
Откуда: parent directory

Сообщение hCORe » 31.08.2005 (Ср) 12:19

Но нужна-то ему быстрая работа с ключами! И тут Collection не "подведет" :)
Моду создают модоки, а распространяют модозвоны.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 69

    TopList