Alexander Speshilov (speshuric) wrote,
Alexander Speshilov
speshuric

Мои первые тесты внешних компонент в новой версии



Решил посмотреть новую технологию. Заодно решить мелокобытовые задачи. В новой версии механизм внешних компонент стал гораздо более ограниченным по применимости. Раньше внешним компонентам позволялось лезть к данным 1С сейчас это обрубили. В принципе ничего страшного, просто немного поменялась концепция.
В качестве задачи, на которой решил потренироваться, выбрал следующие:
  1. В 1С 8 мне сильно не хватает точного таймера для замеров времени выполнения. В 1С 7.7 была недокументированная команда "GetPerformanceCounter", которая тикала по 1 мс, а в новой версии нет инструментов точнее 1 секунды
  2. В 1С нет команды Sleep. Не ну вот что им жалко было тупо протранслировать вызов ОС? Иногда надо подождать 0,01-0,1 секунды в цикле до завершения асинхронных действий (другой системы), а хер. Нельзя этого сделать без цикла.
  3. StringBuilder. Я о его отсутствии как-то даже в ЖЖ жаловался (ну и вариант обхода даже предлагал)

В общем-то получилось без проблем по образцу с ИТС написать нужную внешнюю компоненту и, с небольшой помощью корпорации гугл заставить её запускаться в 1С. Первую задачу я решил через тупую трансляцию вызовов QueryPerformanceFrequency и QueryPerformanceCounter в 1С, вторую - тупой трансляцией Sleep, третью - нагуглил готовый классик. Для линуха я не стал компилировать решение просто потому что на это я бы убил до хрена времени.

Замечания походу:
1. Интерфейс ВК и пример - убогие. Но не настолько, чтобы нельзя было использовать.
2. Жаль, что ВК теперь фактически только на С++. Не, мне не впадлу писать на С++, но иногда хочется инструмент попроще. Если так заботятся о кроссплатформенности, то прикрутили бы Жаву и все были бы щастливы. А еще лучше и .NED.
3. Не понял почему 1Серы не разрешили (кажется) платформе 1С принимать 64-битные целые числа. Из-за этого в вызовах QueryPerformanceFrequency и QueryPerformanceCounter пришлось конвертировать в 32-битное и извращаться с контролем значений, а эти функции достаточно чуствительны, чтобы этого не делать.


Проверил производительность внешних компонент:
Код примерно такой:
    Сообщить(ТекущаяДата());
    ЧастотаСчетчика = Компонента.ПолучитьЧастотуСчетчика();
    ЗначениеСчетчикаНач = Компонента.ПолучитьЗначениеСчетчика();
    Для Сч = 1 По 10000000 Цикл // Десять миллионов повторов
    	ЗначениеСчетчикаКон = Компонента.ПолучитьЗначениеСчетчика();
    КонецЦикла; 
    Сообщить((ЗначениеСчетчикаКон - ЗначениеСчетчикаНач)/ЧастотаСчетчика);
    Сообщить(ТекущаяДата());

Результат:
28.10.2010 3:31:15
28,663215296916228179838499027
28.10.2010 3:31:43

Выполнялось в виртуальной машине с одним процессором (ядром) и 2 ГБ выделенной ей памяти. ЧастотаСчетчика = 3579545. Выполнялось на домашней машине (i7, памяти достаточно). Без вызова "Компонента.ПолучитьЗначениеСчетчика();" время выполнения около 4,6-5 секунд. Я не успел пока проверить, сколько времени 10000000 запусков QueryPerformanceCounter будет выполняться, без возвращения выполнения в 1С, поэтому затраты на вызов пока непонятны (завтра проверю, сейчас спать пойду).
Всё равно 400000-420000 вызовов внешней компоненты в секунду по меркам 1С - вполне достаточная скорость, я ожидал, что результаты будут гораздо хуже.

upd1 Из указанных 28 секунд - 7,8 это чисто вызовы QueryPerformanceCounter. Так что оценка скорости вызовов: 10000000/(28,7-7,8-4,8) ~ 620000. Цикл с методом "ТекущаяДата()" вместо "Компонента.ПолучитьЗначениеСчетчика()" отрабатывает за 8 секунд. Тот же код в COM пока не проверил - это будет следующим апдейтом.
Tags:
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 9 comments