Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Word
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.06.2010, 10:34   #1
Skif-F
Форумчанин
 
Регистрация: 24.03.2010
Сообщений: 349
По умолчанию Отчётик

Как-то я озадачился программной обработкой текста в ворде. Даже обращался с вопросами на форум Произвольная выборка слов
Теперь хочу поделиться с народом результатами своих изысканий.
Надеюсь, что хоть кому-нибудь мой отчёт облегчит жизнь
Вложения
Тип файла: rar Отчёт.rar (11.0 Кб, 19 просмотров)
Нет нерешаемых задач - есть недостаток времени и данных!
Skif-F вне форума Ответить с цитированием
Старый 25.06.2010, 13:32   #2
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Код:
Dim S As Range      'Указатель на предложение
Dim W As Range      'Указатель на слово в предложении
Dim CS(1 To 200) As String  'Слова из предложения (коллекцию поменяли на массив)
Do  'Цикл переборки предложений
    'Разбиваем предложение на слова
    Set W = S.Words.First   'Указатель на первое слово предложения
    For i = 1 To S.Words.Count  'Заполняем массив слов предложения
        CS(i) = LCase(Trim(W.Text))
        Set W = W.Next(Unit:=wdWord, Count:=1)
    Next i
    'Анализ предложения
    For i = 1 To S.Words.Count      'Цикл переборки слов в предложении
       CurWord = CS(i)
	 ...
    Next i

    Set S = S.Next(Unit:=wdSentence, Count:=1)'Переходим к след. предложению
Loop Until S Is Nothing
Цитата:
Данное изменение позволило выиграть примерно 3-5% времени по сравнению с использованием Collection.
А сколько даст выигрыша, если сделать массив динамическим и всё-таки уйти от Words.Count?
Код:
  Dim S As Range      'Указатель на предложение
  Dim W As Range      'Указатель на слово в предложении
  Dim CS() As String  'Слова из предложения (коллекцию поменяли на массив)
  Dim i As Long
  Dim CurWord As String
  Set S = ActiveDocument.Sentences.First
  Do Until S Is Nothing 'Цикл переборки предложений
      'Разбиваем предложение на слова
      Set W = S.Words.First   'Указатель на первое слово предложения
      ReDim CS(1 To S.Words.Count)
      For i = LBound(CS) To UBound(CS)  'Заполняем массив слов предложения
          CS(i) = LCase(Trim(W.Text))
          Set W = W.Next(Unit:=wdWord, Count:=1)
      Next i
      'Анализ предложения
      For i = LBound(CS) To UBound(CS)      'Цикл переборки слов в предложении
         CurWord = CS(i)
'     ...
      Next i
  
      Set S = S.Next(Unit:=wdSentence, Count:=1) 'Переходим к след. предложению
  Loop
Лучше день потерять — потом за пять минут долететь!©

Последний раз редактировалось viter.alex; 25.06.2010 в 13:35.
viter.alex вне форума Ответить с цитированием
Старый 25.06.2010, 14:16   #3
Skif-F
Форумчанин
 
Регистрация: 24.03.2010
Сообщений: 349
По умолчанию

Не знаю, не пробовал.
от Word.Count мы не уходим, так как он присутствует здесь:
Код:
ReDim CS(1 To S.Words.Count)
Вообще, я считаю, что лишние переопределения массива займут больше времени, ведь при каждом проходе надо выполнить команду ReDim!
А команду
Код:
For i = LBound(CS) To UBound(CS)
я бы всё-таки представил как:
Код:
UB = S.Words.Count
For i = 1 To UB
Что не говорите, но вызов функций с передачей параметров, как правило более долгая операция, чем обращение к переменной
Нет нерешаемых задач - есть недостаток времени и данных!
Skif-F вне форума Ответить с цитированием
Старый 25.06.2010, 15:43   #4
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Что ж, тогда я попробую.
Для приложенного документа получен такой результат:
Цитата:
Сообщение от Word 2007
Производительность макроса Arrays1 составляет 82,1562698611136 секунд
Производительность макроса Arrays2 составляет 69,5167000275175 секунд
Цитата:
Сообщение от Word 2003
Производительность макроса Arrays1 составляет 60,9405731734061 секунд
Производительность макроса Arrays2 составляет 53,9718053551499 секунд
Как видно, производительность на довольно большом документе различается в сотых (прям олимпиада). Ну и 2003-й работает пошустрее почти на треть
Note: Arrays1 это твой вариант, Arrays2 — мой.[

Добавлено позже
В результаты тестирования внесены изменения. Вложение изменено. См. это сообщение
Вложения
Тип файла: rar производительность.rar (21.3 Кб, 17 просмотров)
Лучше день потерять — потом за пять минут долететь!©

Последний раз редактировалось viter.alex; 25.06.2010 в 19:13.
viter.alex вне форума Ответить с цитированием
Старый 25.06.2010, 16:15   #5
Skif-F
Форумчанин
 
Регистрация: 24.03.2010
Сообщений: 349
По умолчанию

Ускорение я заметил при замене Words.Count на переменную в заголовках циклов:
Код:
Dim UB As Integer
UB = S.Words.Count
For i = 1 To UB
Как ни странно но получил 11,5 сек вместо 13,02!
При использовании динамического массива ни ускорения, ни замедления я не заметил.
При замене UB на UBount(CS) теряется примерно 0,5 сек
Всё вполне ожидаемо. В любом случае, спасибо за идею - 10-15% выигрыш во времени (что я раньше не заменил Words.Count на переменную?! )
Нет нерешаемых задач - есть недостаток времени и данных!
Skif-F вне форума Ответить с цитированием
Старый 25.06.2010, 16:18   #6
Skif-F
Форумчанин
 
Регистрация: 24.03.2010
Сообщений: 349
По умолчанию

З.Ы. я тестил на своей программе.
разницу в сотые (и даже десяты) доли секунды я игнорирую, поскольку система (операционная) тоже требует внимание процессора
Нет нерешаемых задач - есть недостаток времени и данных!
Skif-F вне форума Ответить с цитированием
Старый 25.06.2010, 19:12   #7
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Должен принести извинения. По невнимательности я тестировал один и тот же макрос. Поэтому такие незначительные различия в производительности. Ошибку исправил и теперь видно, что мой код работает быстрее.
Ещё раз прошу прощения. Изменения в текст сообщения внёс, вложенный файл исправил и перезалил. Результаты не ахти, т.к. запускал на очень старом ноутбуке.
Лучше день потерять — потом за пять минут долететь!©
viter.alex вне форума Ответить с цитированием
Старый 26.06.2010, 10:33   #8
Skif-F
Форумчанин
 
Регистрация: 24.03.2010
Сообщений: 349
По умолчанию

Протестировал изменённый вариант.
Как я и говорил, ускорение даёт замена Words.Count в заголовках циклов на переменную.
Вариант с UBound/LBound чуть-чуть (около 0,1 сек) проигрывает варианту с переменными
Нет нерешаемых задач - есть недостаток времени и данных!
Skif-F вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц