Модераторы: Akina
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Конкатенация против mid() 
V
    Опции темы
ProgramerForever
  Дата 14.5.2010, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 15.11.2006
Где: Новосибирск

Репутация: 2
Всего: 5



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

    For i = 1 To N
        s = s + "DATA"
    Next

Но такой подход неправильный: код работает крайне медленно. Особенно когда строка разрастается в размерах.
Когда-то где-то (=ОБС) я читал. что оператор "&" работает быстрее, чем "+"
Код

    For i = 1 To N
        s = s & "DATA"
    Next

Как оказалось - нет.
А правильнее в таком случае использовать mid().
Делается так (взято с MS):
Код

Dim TestString As String
' Initializes string.
TestString = "The dog jumps"
' Returns "The fox jumps".
Mid(TestString, 5, 3) = "fox"
' Returns "The cow jumps".
Mid(TestString, 5) = "cow"
' Returns "The cow jumpe".
Mid(TestString, 5) = "cow jumped over"
' Returns "The duc jumpe".
Mid(TestString, 5, 3) = "duck"

Как оказалось, можно ускорить код, применяя строки фиксированной длины.
Чтобы оценить скорость работы, написал небольшой код (достаточно просто вставить в новый проект):
Код

'Боев Григорий (ProgrammerForever)(c) 2010

Private Declare Function ApiGetTime Lib "winmm.dll" _
Alias "timeGetTime" () As Long
' Функция apigettime() измеряет промежуток времени с момента запуска Windows.
' Возвращает время с точностью до миллисекунды.

Dim sVar As String         ' Строковая переменная для работы (переменная длина)
Dim sFix As String * 32767 ' Строковая переменная для работы (фиксированная длина)


Dim Report As String    ' Строковая переменная для отчёта
Dim t As Long           ' Хранилище для времени

Private Sub Form_Load()
Report = CStr(Time()) + " : Start" + vbCrLf

' Конкатенация с помощью + (переменная длина)
    t = ApiGetTime()                     'Запоминаем начало теста
Report = Report + vbCrLf + CStr(Time()) + " : Start 'Конкатенация с помощью + (переменная длина)'"
    sVar = ""                            ' Выделяем память, очищаем переменную ' Выделяем память, очищаем переменную
    For i = 1 To 2 ^ 15
        sVar = sVar + "TEST"
    Next
Report = Report + vbCrLf + CStr(Time()) + " : End 'Конкатенация с помощью + (переменная длина)'"
Report = Report + vbCrLf + " Время выполнения: " + CStr(ApiGetTime() - t) + " ms" + vbCrLf

' Конкатенация с помощью & (переменная длина)
    t = ApiGetTime()                     'Запоминаем начало теста
Report = Report + vbCrLf + CStr(Time()) + " : Start 'Конкатенация с помощью & (переменная длина)'"
    sVar = ""                            ' Выделяем память, очищаем переменную
    For i = 1 To 2 ^ 15
        sVar = sVar & "TEST"
    Next
Report = Report + vbCrLf + CStr(Time()) + " : End 'Конкатенация с помощью & (переменная длина)'"
Report = Report + vbCrLf + " Время выполнения: " + CStr(ApiGetTime() - t) + " ms" + vbCrLf

' Использование mid() (переменная длина)
    t = ApiGetTime()                     'Запоминаем начало теста
Report = Report + vbCrLf + CStr(Time()) + " : Start 'Использование mid() (переменная длина)'"
    sVar = Space(2 ^ 16)                    ' Выделяем память, очищаем переменную
    For i = 1 To 2 ^ 15
        Mid(sVar, i) = "TEST"
    Next
Report = Report + vbCrLf + CStr(Time()) + " : End 'Использование mid() (переменная длина)'"
Report = Report + vbCrLf + " Время выполнения: " + CStr(ApiGetTime() - t) + " ms" + vbCrLf




' Конкатенация с помощью + (фиксированная длина)
    t = ApiGetTime()                     'Запоминаем начало теста
Report = Report + vbCrLf + CStr(Time()) + " : Start 'Конкатенация с помощью + (фиксированная длина)'"
    sFix = Space(32767)                    ' Выделяем память, очищаем переменную '
    For i = 1 To 32762
        sFix = "TEST" + sFix
    Next
Report = Report + vbCrLf + CStr(Time()) + " : End 'Конкатенация с помощью + (фиксированная длина)'"
Report = Report + vbCrLf + " Время выполнения: " + CStr(ApiGetTime() - t) + " ms" + vbCrLf

' Конкатенация с помощью & (фиксированная длина)
    t = ApiGetTime()                     'Запоминаем начало теста
Report = Report + vbCrLf + CStr(Time()) + " : Start 'Конкатенация с помощью & (фиксированная длина)'"
    sFix = Space(32767)                    ' Выделяем память, очищаем переменную
    For i = 1 To 32762
        sFix = "TEST" & sFix
    Next
Report = Report + vbCrLf + CStr(Time()) + " : End 'Конкатенация с помощью & (фиксированная длина)'"
Report = Report + vbCrLf + " Время выполнения: " + CStr(ApiGetTime() - t) + " ms" + vbCrLf

' Использование mid() (фиксированная длина)
    t = ApiGetTime()                     'Запоминаем начало теста
Report = Report + vbCrLf + CStr(Time()) + " : Start 'Использование mid() (фиксированная длина)'"
    sFix = Space(32767)                    ' Выделяем память, очищаем переменную
    For i = 1 To 32762
        Mid(sFix, i) = "TEST"
    Next
Report = Report + vbCrLf + CStr(Time()) + " : End 'Использование mid() (фиксированная длина)'"
Report = Report + vbCrLf + " Время выполнения: " + CStr(ApiGetTime() - t) + " ms" + vbCrLf

Report = Report + vbCrLf + CStr(Time()) + " : End"

    MsgBox Report                        ' Выводим окошечком отчёт
    Clipboard.SetText Report             ' И копируем в буфер обмена
    End                                  ' Завершаем работу программы

End Sub

Результат:
Код

15:37:23 : Start

15:37:23 : Start 'Конкатенация с помощью + (переменная длина)'
15:37:29 : End 'Конкатенация с помощью + (переменная длина)'
 Время выполнения: 5422 ms

15:37:29 : Start 'Конкатенация с помощью & (переменная длина)'
15:37:34 : End 'Конкатенация с помощью & (переменная длина)'
 Время выполнения: 5446 ms

15:37:34 : Start 'Использование mid() (переменная длина)'
15:37:34 : End 'Использование mid() (переменная длина)'
 Время выполнения: 6 ms

15:37:34 : Start 'Конкатенация с помощью + (фиксированная длина)'
15:37:36 : End 'Конкатенация с помощью + (фиксированная длина)'
 Время выполнения: 1833 ms

15:37:36 : Start 'Конкатенация с помощью & (фиксированная длина)'
15:37:38 : End 'Конкатенация с помощью & (фиксированная длина)'
 Время выполнения: 1898 ms

15:37:38 : Start 'Использование mid() (фиксированная длина)'
15:37:38 : End 'Использование mid() (фиксированная длина)'
 Время выполнения: 4 ms

15:37:38 : End

Надеюсь это кому-нибудь будет полезно. С этого момента буду повсеместно юзать mid() и фиксированные строки.

Это сообщение отредактировал(а) ProgramerForever - 14.5.2010, 11:48
PM MAIL WWW ICQ   Вверх
Akina
Дата 14.5.2010, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 34
Всего: 454



Попробуй ещё сравнить скорость работы на динамических и на фиксированных строках...


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
ProgramerForever
  Дата 14.5.2010, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 15.11.2006
Где: Новосибирск

Репутация: 2
Всего: 5



На фиксированных строках работает быстрее. Правда смысла нет использовать фиксированные строке без mid(), т.к.
Код

sFix=sFix+"Любая_строка"

ничего не изменит, т.к. "лишние" символы проигнорируются.
А если в цикле делать наоборот:
Код

Dim sFix as String*10
    For i = 1 To 9
        sFix = cstr(i) + sFix
    Next

то данные будут накапливаться шиворот-навыворот: "987654321_"
Изменил код в первом посте, чтобы не плодить сущности.
PM MAIL WWW ICQ   Вверх
Akina
Дата 14.5.2010, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 34
Всего: 454



Я вообще-то предполагал, что ты будешь использовать ПРОЦЕДУРУ mid()
Код

Mid(sFix,place) = "String to insert into"



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
ProgramerForever
  Дата 14.5.2010, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 15.11.2006
Где: Новосибирск

Репутация: 2
Всего: 5



Ээ.. Так и делаю:
Код

Mid(sFix, i) = "TEST"

PM MAIL WWW ICQ   Вверх
Akina
Дата 14.5.2010, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 34
Всего: 454



а, пардон... посмотрел код конкатенации и замечание насчёт конкатенации в начало, а собсно тест-код проглядел.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "VB6"
Akina

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по VB обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • Используйте теги [code=vb][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Akina.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | VB6 | Следующая тема »


 




[ Время генерации скрипта: 0.0701 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.