gifts2017

Оптимизация типовых функций из кода 1с в 1С:Предприятие 8.Х

Опубликовал Артур Аюханов (artbear) в раздел Программирование - Практика программирования

Оптимизация типовых функций/кода 1с в 8-ке - оптимизация типовых функций 1С типа ВыделитьСлово, РазложитьСтрокуВМассивПодстрок и т.д.

Оптимизация типовых функций/кода 1с в 8-ке - оптимизация типовых функций 1С типа ВыделитьСлово, РазложитьСтрокуВМассивПодстрок и т.д.

В продолжение обсуждения http://infostart.ru/public/64222

Все алгоритмы предлагаю выкладывать в виде:

Название типовой/штатной функции 1С - например, ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок

Можно приложить типовую реализацию функции

Далее выкладываем свой оптимизированный вариант, который должен 100% выполнять ту же самую функцию.

Возможно описать некоторые ограничения, связанные с использованием оптимизированной функции - например, нужна ли первоначальная инициализация (может быть медленной)

  1. Функция ОбщегоНазначения. РазложитьСтрокуВМассивПодстрок

Описание

Функция "расщепляет" строку на подстроки, используя заданный разделитель. Разделитель может иметь любую длину.
Если в качестве разделителя задан пробел, рядом стоящие пробелы считаются одним разделителем, а ведущие и хвостовые пробелы параметра Стр игнорируются.
Например,
РазложитьСтрокуВМассивПодстрок(",ку,,,му", ",") возвратит массив значений из пяти элементов, три из которых - пустые строки, а РазложитьСтрокуВМассивПодстрок(" ку му", " ") возвратит массив значений из двух элементов

Параметры:
  Стр - строка, которую необходимо разложить на подстроки.
  Параметр передается по значению.
  Разделитель - строка-разделитель, по умолчанию - запятая.

Возвращаемое значение:
  массив значений, элементы которого - подстроки

Самая быстрая реализация этого метода ( по состоянию на 28.01.2010)

 

Перем Script2;

Функция РазложитьСтрокуВМассив(Строка, Разделитель = ",") Экспорт
    Возврат Script2.eval("Split(""" + Строка + """, """ + Разделитель + """)").Выгрузить();
КонецФункции

Процедура Инит() Экспорт
    Script2 = Новый COMОбъект("MSScriptControl.ScriptControl");
    Script2.Language = "vbscript";
КонецПроцедуры


[u]Ограничения реализации - требуется предварительная инициализация[/u]

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Тест_РазложитьСтрокуВМассивПодстрок.epf
.epf 10,37Kb
10.11.14
54
.epf 10,37Kb 54 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. dushelov (Душелов) 28.01.10 14:14
Предлагаю в тело публикации добавлять полученные алгоритмы и сделать общий тест на это дело.
2. Евгений Люлюк (Evg-Lylyk) 28.01.10 14:18
Давайте только опишем какие функции нужно оптимизировать
3. Алексей Константинов (alexk-is) 28.01.10 14:23
Нужно было заводить не статью, а группу
4. Артур Аюханов (artbear) 28.01.10 14:26
Обновил публикацию.
По тестированию предполагаю использовать юнит-тестирование в том виде, как выкладывал в ветке по RegExp.
5. dushelov (Душелов) 28.01.10 14:28
(3) Публикацию можно расширить.
6. Артур Аюханов (artbear) 28.01.10 14:34
(5) Расширил публикацию.
Выложил Тест_РазложитьСтрокуВМассивПодстрок.epf
4 сравнения -
Выполнений: 1 000 Функции из Бух 1.6 и КОРП 2.0 время: 797 мс
Выполнений: 1 000 функций на RegExp время: 1 016 мс
Выполнений: 1 000 функций на VBScript время: 390 мс
Выполнений: 1 000 Функции ЗначениеИзСтрокиВнутр время: 641 мс
7. Алексей Константинов (alexk-is) 28.01.10 15:14
(6) "из Бух 1.6 и КОРП 2.0" - это тоже оптимизированный мною вариант. "Родной вариант" выглядит несколько иначе. Он есть в первоначальном варианте теста из http://www.infostart.ru/public/64222/ Тест прикрепил к сообщению.

Предлагаю включить его "как есть", т.е. не загонять в 1 строку. Тогда разница в производительности будет очевиднее.

И еще замечание по замерам в тестах. На полученные результаты тестирования влияют циклы. Что искажает время результатов. Нужно из результатов тестов исключать время на циклы. Тогда останется только время выполнения самих функций. Примеры таких тестов можно посмотреть здесь http://www.infostart.ru/public/19021/
8. Алексей Константинов (alexk-is) 28.01.10 15:16
+7 ...что-то тест не прикрепился :(
Прикрепленные файлы:
Тест.epf
9. Артур Аюханов (artbear) 28.01.10 15:19
(8) В подфоруме завел новую тему по этой функции
10. Артур Аюханов (artbear) 28.01.10 15:23
(8) ОФФ. Я тебе по разукрашке ответил - не очень удобно работать :)
11. Артур Аюханов (artbear) 28.01.10 15:53
(7) Исправился - исключил время циклов.
13. Артур Аюханов (artbear) 28.01.10 16:29
(12) Женя правильно сказал, что ради подобной функции не нужно юзать отдельную компоненту.
Вполне можно написать простой код на ВБ-скрипт и оформить его в виде отдельной функции 1С или класса 1С.

Да и сортировка массива ИМХО довольно редкий случай, намного чаще работаешь с сортировкой других коллекций.
14. Артур Аюханов (artbear) 28.01.10 16:34
(12) Завел новую подтему "Сортировка массива"
http://infostart.ru/public/64770/forum/topic/30873/
15. Михаил Ражиков (tango) 28.01.10 16:39
(13) в УТ нашел два места, где тупым перебором ищется значение в массиве
16. Артур Аюханов (artbear) 28.01.10 17:41
Еще кандидаты на оптимизацию из общего модуля "ОбщегоНазначения"
ТолькоЦифрыВСтроке
ВыделитьСлово
ЕстьНеЦифры
МассивыИдентичны
УдалитьНеЗаполненныеЭлементыМассива
УдалитьПовторяющиесяЭлементы
УдалитьПовторяющиесяЭлементыМассива
17. Михаил Ражиков (tango) 28.01.10 18:16
только цифры:

Попытка
нн = Число(Тестстрока);
Исключение
Сообщить("блин, не только цифры...");
КонецПопытки
18. Алексей Прилепский (IamAlexy) 28.01.10 21:01
лучше бы закрытие месяца в типовых БП на SQL базах оптимизировали бы :)

19. Валерий Дубовой (Valerich) 29.01.10 14:20
(18) на этом сайте уже выложено несколько вариантов оптимизаций
20. Артур Аюханов (artbear) 29.01.10 16:23
(17) Блок Попытка-КонецПопытки очень медленный как правило.
Нужно потестить подобное преобразование :)
21. desty (lustin) 31.03.10 10:11
Артур - тут такое дело

вот такой тест
Процедура ПроверитьРазборСтроковогоПараметраScriptЗначенияСКавычкамиВВнутри() Экспорт
	первыйЭлемент = Символ(34)+"я" +Символ(34);
	второйЭлемент = Символ(34)+"тест"+Символ(34);
	результат = ОбщегоНазначенияАльтернативный.РазложитьСтрокуВМассивПодстрок(первыйЭлемент+"="+второйЭлемент,"=");
	Я_Тест.ПроверитьРавенство(результат[0],первыйЭлемент);
	Я_Тест.ПроверитьРавенство(результат[1],второйЭлемент);
КонецПроцедуры
...Показать Скрыть


не пройдет на функции ОбщегоНазначенияАльтернативный.РазложитьСтрокуВМассивПодстрок
Функция РазложитьСтрокуВМассив(Строка, Разделитель = ",") Экспорт
    Возврат Script2.eval("Split(""" + Строка + """, """ + Разделитель + """)").Выгрузить();
КонецФункции
...Показать Скрыть


с ошибкой компиляции VBScript из-за недопустимого знака

сейчас пробую сделать так чтобы тест проходил

22. desty (lustin) 31.03.10 12:12
(21)

блин, а не получается пока с наскока придумать как обойти это финт - туплю наверное :|
23. Артур Аюханов (artbear) 31.03.10 12:20
(21) "Не пройдет" или уже не проходит? ты в реале протестил?
24. desty (lustin) 31.03.10 13:24
(23) вечно я недоформулирую

"Не прошел" имелось ввиду;

у меня выдало в реальности, я и написал тест (как Федор советовал - добейтесь вначале чтобы тест не проходил)
25. rasswet (rasswet) 01.04.10 08:38
"требуется предварительная инициализация" каким образом?
26. Артур Аюханов (artbear) 03.06.10 16:13
(25) До вызова быстрого основного метода РазложитьСтрокуВМассив
предварительно нужно где-то вызвать метод Инит() - он довольно тормозной :(
27. Денис Яковлев (iceflash) 11.08.10 19:02
Вообще, мне кажется данная "оптимизация" палка о двух концах. Из одного интерпретатора передавать управление на исполнение кода в другой=)
Тут наверное стоит подходит со стороны. что можно сделать средствами 1ц, а что средствами сторонних скриптовых движков\ВК. И на сколько я знаю обмен и взаимодействие по технологии COM достаточно ресурсоемкий (процессор, оперативная память), и данный вывод я делаю не как разработчик на 1ц, а как системный программист, 1ц - это "дуновение потребностей"=) Т.е. например когда действительно нужно применить регулярку, имеет смысл использовать JS регулярку=)
А вообще конечно хотелось бы увидеть примеры замеров производительности (обязательно раз по 10 как минимум, с средним арифметическим) 8-)
28. Serg G (Serg G) 10.06.15 04:24
результаты тестов зависят от многих факторов. Например, большая часть времени уходит на создание обьекта (New RegExp) , на чем часто играют создатели, так сказать, "более быстрых альтернатив". Если же он создан и уже весит в памяти , то отработает, наверняка, быстрее всех. Хотя, Split() - это слишком примитивно.

Во-вторых, существенно влияет последовательность тестов. Т.е., что вы тестируете первым, то и покажет лучшие СВОИ результаты. Это связанно с оперативной памятью. (Кто-то ранее заметил, что запись в одну переменную - но физически это не так.)
RegExp - проверенный временем обьект, очень мощный и нужный. Главный минус, что он сторонный/внешний и ОСевой.
(Могу ошибаться, но в учебных платформах 1C com-обьекты тоже не подключаются. )

И всё же, при всех плюсах RegExp-a, желательно использовать стандартные наборы функций. Впринципе, это закон любой седы.

Реализовать такой обьект, как RegEx, в 1с не реально, имхо! Лучше лоббировать его включение и оптимизацию в саму платформу.
29. Артур Аюханов (artbear) 10.06.15 12:06
Сейчас, конечно, я уже не найду результатов тестирования, 5 лет все-таки прошло :)
Но проверял на нескольких разных алгоритмах, естественно, на большом количестве выполнений.
30. Артур Аюханов (artbear) 10.06.15 12:07
(28) >существенно влияет последовательность тестов
Не соглашусь.
Нет такой явной зависимости от последовательности выполнения
31. Serg G (Serg G) 10.06.15 21:37
(30) artbear, Ну, я только знакомлюсь с 1с, так что, извините, 2010 для меня тоже самое что и 2020. :)
Имеется ввиду, если тест идет одной процедурой, последовательно.
Когда-то давно, тестировал ADO vs DAO на создание нескольких десятков и даже сотен тысяч строк в таблице... Впоследствии выяснилось, , последний покажет худший СВОЙ результат, чем будь он первым. Понимаете, даже хранение результатов первого теста в переменной уже уменьшает оперативную память, что приведет к более медленной отработке второго теста.
Такие "микротесты" (и тут http://infostart.ru/public/64222/) нужно проводить на идеально "вылизанных" машинах: без лишних служб, без сетей, без антивирусов и тп, что может "тормознуть" ОС на мгновение. И то... В общем, если проводить тесты, то уж на максимальных нагрузках.

>...на большом количестве выполнений.
Разбейте томик К.Маркса на слова, например, где результаты будут более 5 сек, хотя бы.


ps: Еще, подозреваю, что скорость wscript и сscript разная и точно зависит от установленных комплексов защиты компьютера и их настройки. Т.е. на разных машинах, результаты могут отличаться.
А на чем работает 1с при Eval()(Выполнить()) или на дефолте в системе?
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа