Категории каталога

Моё творчество [11]
Тут я буду распологать мои задумки, относящиеся, в основном, к области программирования, но не ограничиваясь ею. Читайте и получайте удовольствие. И оставляйте отзывы в гостевой.

Форма входа

Приветствую Вас Гость!

Поиск

Статистика

<< InfraRed >>

Каталог статей

Главная » Статьи » Моё творчество

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

  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() и фиксированные строки.


Источник: http://InfraRed.Ucoz.Ru
Категория: Моё творчество | Добавил: Editor (14.05.2010) | Автор: Боев Григорий Олегович
Просмотров: 628 | Комментарии: 3 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]