Производительность выполнения кода 1С:Предприятие 8.х

Вопрос производительности кода на языке 1С возникает у каждого программиста, который его использует или всерьез интересуется. Из публикаций известно, что 1С - это не компилятор и не интерпретатор, а гибридная машина интерпретирующая байт-код, полученный компиляцией исходного кода. Очевидно, что это не может работать слишком быстро, но хочется знать точнее, что можно ждать от программы, а чего нет. Кроме этого общего вопроса, есть еще много частных вопросов, связанных с рефакторингом кода. Существует масса различных способов обработки программных данных, которые могут существенно отличатся по скорости выполнения. В критически узких алгоритмах очень важно понимать, какие способы "медленные, но удобные", а какие "ужасные, но быстрые".

Настоящая публикация содержит описание методики и результаты измерения скорости выполнения основных языковых конструкций платформы 1С:Предприятие 8.х.

  •  Производительность //old.mista.ru
  • Заметочки про 1С:Предприятие 8 (редакция 22.06.2012) //infostart.ru

Метод исследования

Древним дедовским способом оценки производительности языка было написании "цикла до миллиона" и запуск его с секундомером в руках. Чтобы измерить затраты времени на какую-либо языковую конструкцию, ее нужно поместить в этот цикл и общее время затрат разделить на число циклов. Способ этот бесспорно простой, но довольно неточный, поскольку он не учитывает затраты на сам цикл, и оценить их точно тоже не просто. Поэтому для повышения точности оценки был применен дифференциальный метод.

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

Например, оценка времени операции присваивания была выполнена следующим способом:

Итоговое время выполнение исследуемой конструкции определяется выражением: ((Дата2 - Дата1) - (Дата 1 - Дата0)) / (1000 * Ц)

Условия проведения

Измерения скорости выполнялись в системе:

  • CPU: AMD Athlon X4 760K Quad Core
    • Clocks: 4GHz 100MHz x40
    • Cache: 16KBx4/64KB 2
  • Board: ASRock FM2A88X Pro3+
  • RAM: DDR3 666MHz Dual 1500MHz 9-9-9-24-33
  • OS: Windows 10 Pro x64 1909
  • CPU-Z Bench: Single Thread 230 (Multi Thread: 760)
  • Платформа: 1С:Предприятие 8.3 (8.3.17.1386)

Результаты

Исследование времени выполнения различных языковых конструкций установило, что самой быстрой операцией является операция сложения с числовой переменной содержащей значение 1. В дальнейшем время самой быстрой операции было принято за единицу "такт" для сравнения с результатами других конструкций, приведенных в таблице. В первой колонке таблицы приведен фрагмент второго цикла, а исследуемый фрагмент отличающий второй цикл от первого выделен жирным:

Языковая конструкция Bремя выполения (с) циклов в секунду
(C⁻¹)
Время на "такт"
(T)
// суммирование с числовой переменной содержащей значение 1
В = 1;
Для А = 1 По 500000 Цикл
Б = А + В;
0,000000275 3 631 961 1.000
// присвоение переменной числового значения другой переменной
Для А = 1 По 500000 Цикл
Б = А;
Б = А;
0,000002964 337 418 10,764
// суммирование с увеличивающимся числовым значением
Для А = 1 По 500000 Цикл
Б = А + А;
0.000000522 1 915 709 1,896
// суммирование с числовой константой =1
Для А = 1 По 500000 Цикл
Б = А + 1;
0,000000556 1 798 561 2,019
// суммирование с числовой константой =1234567890
Для А = 1 По 500000 Цикл
Б = А + 1234567890;
0,000000752 1 329 787 2,731
Для А = 1 По 500000 Цикл
Б = ТекущаяУниверсальнаяДатаВМиллисекундах();
Б = ТекущаяУниверсальнаяДатаВМиллисекундах();
0,000004049 247 005 14,704
Для А = 1 По 500000 Цикл
ТекущаяУниверсальнаяДатаВМиллисекундах();
ТекущаяУниверсальнаяДатаВМиллисекундах();
0,000003523 283 889 12,794

Пустой цикл переменной А (длина имени не влияет) x1000000 5850ms

Суммирование Б = Б + А; x1000000 8895ms

Субцикл Для Б = 1 По 0 Цикл 8761

Субцикл Для Б = 1 По 1 Цикл 14339

Б = 123; 8729

Б = ТекущаяУниверсальнаяДатаВМиллисекундах(); 9527

Б = Ф();//Возврат 123; 41530

П(А);// 38580

П(А);//Б=А; 41637

Ф(А);//Возврат А; 41529

А+А 8816

А*А 500К 5085

А*А 1M 10147

 

Дополнение

В ходе проведения исследования производительности были выявлены некоторые нюансы в работе оператора Выполнить(<код>).

  • Скорость выполнения кода одинакова на НаКлиенте и НаСервере
  • Скорость выполнения кода по сравнению с обычным модулем снижается от 4%, обычно 6%
  • В коде доступны все локальные переменные на уровне оператора Выполнить
  • Взаимодействие кода с локальными переменными снижает скорость выполнение от 15%
  • Компиляция кода требует время около 15ms/KB/GHz (на каждый KB кода на 1GHz частоты CPU)

Пример выполнения циклов в операторе Выполнить с взаимодействием и без взаимодействия с локальными переменными:

 

Источники

  • 1С: Ассемблер — пишем чистый байт-код для стековой машины 1С: Предприятие //habr.com
  • 1С — Добро и зло. Расстановка точек в холиварах вокруг 1С //habr.com
  •  Производительность //old.mista.ru
  • Заметочки про 1С:Предприятие 8 (редакция 22.06.2012) //infostart.ru

Leave a Reply