Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

5 Июль 2020, 15:49 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Вы можете задать вопрос по LibreOffice или Apache OpenOffice без регистрации, используя форму
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1   Вниз
  Печать  
Автор Тема: Производительность функции Replace LibreOffice Basic  (Прочитано 939 раз)
0 Пользователей и 1 Гость смотрят эту тему.
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 61


WWW
« Стартовое сообщение: 24 Апрель 2020, 20:27 »

Добрый день! У меня проблема со скоростью работы функции Replace LibreOffice Basic.

Код:
Sub TestReplace
  Dim s as String, i as Long, n as Long, t as Long
  n=100000
  s=Space(n) & "1"
  i=InStr(s, "1")   ' мгновенно даже при n=4000000
  t=GetSystemTicks
  s=Replace(s, " ", "*") 
  Msgbox "n=" & n &  " time=" & (GetSystemTicks-t)
End Sub

При значениях n>=100000 время работы функции увеличивается пропорционально квадрату числа n. При этом функция InStr отрабатывает мгновенно.
Можно, разумеется, воспользоваться соответствующими UNO, но хотелось бы эфффективной работы "родных" функций Basic.

Моя версия: Win 10, LO 6.3.3.2 (x64).
Записан

Владимир.
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 919


« Ответ #1: 24 Апрель 2020, 22:06 »

Ну, SbRtl_Replace оптимизировать-непереоптимизировать.
Записан

С уважением,
Михаил Каганский
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 953


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #2: 24 Апрель 2020, 23:20 »

У меня проблема со скоростью работы функции Replace LibreOffice Basic.
При этом функция InStr отрабатывает мгновенно.
Ну, вы сравнили... две большие разницы. Функция InStr находит подстроку в строке (в вашем примере последний символ в строке состоящей из 100001 символа), а функция Replace заменяет 100000 пробелов на звёздочки.

Для честного сравнения если InStr ищет только один последний символ, то и Replace должна искать и заменять только один последний символ. В этом случае поиск и замена в 2 — 3 раза медленней чем только поиск, что нормально. Проверьте:

Код:
Sub TestReplace
  Dim s as String, i as Long, n as Long, t as Long
  n=100000000
  s=Space(n) & "1"
  t=GetSystemTicks
  i=InStr(s, "1")            'при n = 100 000 000 у меня time=112
  Msgbox "i=" & n &  " time=" & (GetSystemTicks-t)

  t=GetSystemTicks
  s=Replace(s, "1", "*")     'при n = 100 000 000 у меня time=293
  Msgbox "n=" & n &  " time=" & (GetSystemTicks-t)
End Sub
Записан

kompilainenn
Мастер
*****
Offline Offline

Сообщений: 2 972



« Ответ #3: 24 Апрель 2020, 23:22 »

Ну, SbRtl_Replace оптимизировать-непереоптимизировать.
Это ты тонко
Записан

Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 919


« Ответ #4: 25 Апрель 2020, 01:17 »

Это исправление сделает функцию мгновенной.

А пока можете значительно ускорить её, если зададите ей чувствительность к регистру.
Записан

С уважением,
Михаил Каганский
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 61


WWW
« Ответ #5: 25 Апрель 2020, 13:29 »

Добрый день, коллеги. Спасибо за ответы, и, особенно, за впечатляющую конструктивную реакцию! Подождем версии 7.

Еще пара замечаний в части Replace.

1. Ограничение на максимальное значение 65535 параметра Start,  указанное в документации, выглядит явным атавизмом. Правда, этот параметр используется редко.

2. О регистре символов. Тестировал на:

Код:
msgbox Replace("Default is binary compare", "BINARY", "Text")

Если присутствует оператор Option VBASUPPORT 1, то производится сравнение с учетом регистра символов (бинарное), иначе без учета регистра символов (текстовое), что, на мой взгляд, логично (соответствует умолчанию VBA). Было бы неплохо указать об этом в документации по функции Replace.

Проверил на вчерашней тест-системе кузину Replace - SUBSTITUTE из семьи Sheet.FunctionAccess.Callfunction. Те же симптомы. Может быть, ее тоже вылечить?



 
« Последнее редактирование: 25 Апрель 2020, 13:34 от sokol92 » Записан

Владимир.
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 919


« Ответ #6: 25 Апрель 2020, 13:57 »

1. Ограничение на максимальное значение 65535 параметра Start,  указанное в документации, выглядит явным атавизмом. Правда, этот параметр используется редко.

Добавил в tdf#132390.

2. О регистре символов. Тестировал на:

Код:
msgbox Replace("Default is binary compare", "BINARY", "Text")

Если присутствует оператор Option VBASUPPORT 1, то производится сравнение с учетом регистра символов (бинарное), иначе без учета регистра символов (текстовое), что, на мой взгляд, логично (соответствует умолчанию VBA). Было бы неплохо указать об этом в документации по функции Replace.

Напишите отдельный баг.

Проверил на вчерашней тест-системе кузину Replace - SUBSTITUTE из семьи Sheet.FunctionAccess.Callfunction. Те же симптомы. Может быть, ее тоже вылечить?

И этот баг напишите.
Записан

С уважением,
Михаил Каганский
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 61


WWW
« Ответ #7: 25 Апрель 2020, 14:31 »

Очередное cпасибо! Писать про баги пока еще Заратустра статус не позволяет. Подмигивающий
« Последнее редактирование: 25 Апрель 2020, 14:34 от sokol92 » Записан

Владимир.
kompilainenn
Мастер
*****
Offline Offline

Сообщений: 2 972



« Ответ #8: 25 Апрель 2020, 14:39 »

Очередное cпасибо! Писать про баги пока еще Заратустра статус не позволяет. Подмигивающий
чего чего? Какой ещё статус? вот адрес bugs.documentfoundation.org , заводите учетку и пишите (только на английском пожалуйста). Баг трекер всегда открыт для всех, ни про какие "статусы" я никогда не слышал
Записан

Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 61


WWW
« Ответ #9: 25 Апрель 2020, 15:18 »

Спасибо! И еще вопрос:

Код:
s=replace("ABCD","A","B",,,1)

устанавливает в s значение !!br0ken!!

Это - какое-то соглашение разработчиков об обработке исключительных ситуаций, связанных с синтаксисом Basic?

В то же время запись:

 
Код:
s=replace("ABCD","A","B", Compare:=1)

работает штатно.
Записан

Владимир.
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 919


« Ответ #10: 25 Апрель 2020, 16:01 »

А это повод для третьего (вашего) бага про эту функцию (я уже свои три написал).

Реально это ошибка неправильной проверки типа переданной переменной. Вы указали ,,, - все пропущенные параметры передаются как объект "ошибка - отсутствующий именованный параметр" (ошибка 448). Функция этого не проверяет, и пытается этот объект превратить в число (получается 448). Попытка вернуть подстроку четырёхсимвольной строки начиная с 448 позиции выдаёт такую ошибку (до моего исправления выше) или пустую строку (после того исправления) вместо того, чтобы эту ошибку считать "используй значение по умолчанию" (1).
Записан

С уважением,
Михаил Каганский
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 61


WWW
« Ответ #11: 25 Апрель 2020, 16:28 »

 Спасибо, как всё, оказывается, интересно! Улыбка
« Последнее редактирование: 26 Апрель 2020, 13:42 от sokol92 » Записан

Владимир.
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 61


WWW
« Ответ #12: 26 Апрель 2020, 13:42 »

Поменял версию на Win10 LO Версия: 6.4.3.2 (x64).

Третий отмеченный Михаилом баг - некорректная работа с символами юникода из страницы 01 и далее (в частности, с буквами кириллицы).
Посмотрел по ссылке код функции SbRtl_Replace. В строках 1286 и 1287 используется функция (toAsciiUpperCase), которая про юникод ничего не знает (поскольку значительно старше по возрасту). Эта же старушка не дает корректно работать функциям Basic InStr, InStrRev, Strconv (нет в документации), Curdir.

В том же модуле C++ есть функции SbRtl_LCase, SbRtl_UCase, SbRtl_StrComp, которые с юникодом обращаются корректно.

Проверяем корректность работы Instr и InstrRev(только с поддержкой VBA) при работе с кириллицей по сравнению с латынью:

Код:
Option VBASUPPORT 1
Sub TestInstr
  Dim v
  For each v In array("s", "ш")  
    Msgbox "Instr: text1=" & Ucase(v) & " text2=" & v & " compare=1" & " result=" & _
           Instr(1, Ucase(v), v, 1) & chr(10) &  _
           "InstrRev: text1=" & Ucase(v) & " text2=" & v & " compare=1" & " result=" & _
           InstrRev(Ucase(v), v, 1, 1) &  chr(10)
  Next v
End Sub

Вывод: результаты работы с кириллицей некорректны.

В реализации других функций Basic использование toAsciiUpperCase (toAsciiLowerCase), на мой взгляд, не опасно, поскольку эти функции (обработка даты, времени...) не взаимодействуют с  текстом, содержащий символы юникода с кодами >=U+0100
« Последнее редактирование: 26 Апрель 2020, 13:50 от sokol92 » Записан

Владимир.
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 919


« Ответ #13: 26 Апрель 2020, 14:18 »

Третий отмеченный Михаилом баг - некорректная работа с символами юникода из страницы 01 и далее (в частности, с буквами кириллицы).

Вы про tdf#132389?

В строках 1286 и 1287 используется функция (toAsciiUpperCase)

... после исправления - в строках 1282 и 1283.

В реализации других функций Basic использование toAsciiUpperCase (toAsciiLowerCase), на мой взгляд, не опасно, поскольку эти функции (обработка даты, времени...) не взаимодействуют с  текстом, содержащий символы юникода с кодами >=U+0100

Ой не факт. Обработка дат вида "5 октября" вполне себе возможна. Ну, и для полноты занудствования - "с кодами >= U+0080".

Вы вполне можете попробовать это всё поправить. Я готов Вам помочь с развёртыванием среды разработки и вопросами по патчам. Мне так кажется, что у Вас всё получится.
Записан

С уважением,
Михаил Каганский
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 61


WWW
« Ответ #14: 26 Апрель 2020, 15:53 »

Спасибо!
Записан

Владимир.
Страниц: 1   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!