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
Сейчас интересует создание внешних компонент
Правда меня больше интересует под 7.7
Под 7.7 есть шаблон для создания ВК (кажется на ИТС был когда-то раздел "Методика создания ВК").
Но под 7.7 в основном писали все на делфи (и как правило не по шаблону :))
Он и сейчас есть. Даже 2 - старый и новый.
Написание ВК (статьи с ИТС) чем-то принципиально отличаются от 7.7 и 8.0?
Просто для клюшек писал много, а вот под 8.2 как-то не приходилось :)
Между 7.7, 8.0 и 8.1 отличия незначительные. Везде это СОМ-объекты с определённым интерфайсом, правда часть доступных функций в 8.0, 8.1 порезана. По сути из-за того, что 8.1 нормально поддерживает работу с COM (в том числе обработка событий), то внешние компоненты в 8.1 были уже почти не нужны.
8.2 принципиально отличается тем, что кроме COM есть еще свой API - "Native API". Если всё делать тщательно и аккуратно, то такая ВК запускается и во всех режимах работы (сервер предприятия под вин32/вин64/лин, толстый клиент, тонкий клиент, веб-клиент IE, веб-клиент Firefox) - в этом может быть смысл. Из-за этой долбаной кроссплатформенности из языков остался тока С++ (или писать свою обёртку к вызовам функций .NET/JRE из неуправляемого кода). Я сейчас хочу понять для себя, достаточна ли производительность ВК, чтобы на неё скидывать "легковесные" задачи, которые не реализованы платформой (пример - в посте). Если заработает, то можно приемнять ВК именно в этом контексте.
Здравствуйте. Наткнулся на странность: две сэмпловые компоненты, одна - на vb, другая - на C#. Первая отлично работает в 7.7, вторая - только в 8.2. Обе - по COM-технологии (не NAPI), вроде бы собраны без особых различий (ну, за исключением разной обработки проектов в VS2010). Но С# почему то не хочет работать в 7.7.
Ошибка: Ошибка при инициализации объекта из компоненты <Неизвестная компонента>
При этом объект создается, но с каким то странным именем... (блок данных компоненты с подчеркиванием, вместо ProgID).
Может подскажете хотя бы в какую сторону копать?
Я вот такую функцию юзаю:
Функция Таймер()
Script = New COMОбъект("MSScriptControl.ScriptControl");
Script.language = "vbscript";
Timer = Script.Eval("Cdbl(Timer)");
Return Timer;
КонецФункции
А можно исходники на почту кинуть? начал разбираться с ВК, хочу прикрутить библиотеку Qt к 1С кое что уже получилоьс, только вот не пойму как вернуть результат выполнения функции из вк в 1с? мож подскажешь?
Так вроде если COM-технология используется, то в функции
public void CallAsFunc(int lMethodNum, ref object pvarRetValue, ref System.Array paParams)
вторым параметром (pvarRetValue) - как раз место, куда надо слить значение для 1С... (Осталось только с соответствием типов разобраться - но там вроде не сложно)