1С с "плюсами"

— Разработана методика подключения внешней компоненты, снимающая ограничения на типы данных аргументов и возвращаемого значения.
— Проведено документирование основных типов данных (объектов, интерфейсов) платформы.
— Разработан объект «Делегат» для реализации функциональных объектов (указатель-на-функцию).
— Разработана концепция итератора произвольного доступа для основных контейнеров платформы с целью сопряжения со стандартной C++ библиотекой.
— В процессе разработки механизм 1С классов (наследование, интерфейсы) для возможности использования парадигм объектно-ориентированного программирования на уровне кода.

 

 И еще, тезисно:

— Файлов к скачиванию здесь пока не будет. Все еще весьма сыро. Основной целью публикации является дискуссия.

— Тесты проводились для win32::v8.3.4.365 — v 8.3.6.2237. Для win64, lin32, lin64 и для v8.2.19.130 только оценена возможность – работать будет при минимальных изменениях.

— В процессе экспериментов ни один проприетарный байт не пострадал. Т.е. оригинальные бинарники 1С я не патчу ни на диске, ни в памяти.

— Все исключительно в познавательных целях и с целью модификации программы для улучшения ее характеристик в соответствии с ее предназначением. Все имена вымышлены и совпадения случайны.

— 1С начал изучать вплотную недавно, много еще не знаю. До этого VB++C/C++. Целью работ был перенос части возможностей VB в 1С.

— Также заранее прошу прощения за стиль изложения – эпистолярный жанр не мой конек.

 

 Итак…

            Решаем простейшую задачу: Есть ТаблицаЗначений и в ней колонки [количество] и [цена]. Нужно вычислить СУММА([количество] * [цена]).

Здесь и далее время выполнения алгоритма засекается через ::GetTickCount(), т.е. является относительной величиной.

Код 1С:

Функция СчитатьТаблицу(Котейнер)
перем элем;
перем итого;
итого = 0;
для каждого элем из Котейнер цикл
итого = итого + элем[1] * элем[2];
КонецЦикла;
возврат итого;
КонецФункции

Код Си (иллюстративно):

...
cRows = pITable->getRowCount();
for (iRow = 0; iRow < cRows; iRow++)
{
if (pITable->getValueAt(iRow, 1).getIValue()->getNumeric(numQty) &&
pITable->getValueAt(iRow, 2).getIValue()->getNumeric(numPri))
{
numTot += numQty * numPri;
}
}
pOutRetValValue->assign(numTot);
...

 

Результаты:

*———— сумма произведений по ТаблицеЗначений —————

* строк = 100 000

* посчитано СУММА([кол]*[цена]) в Си: результат = 333 328 333 350 000, время = 94

* посчитано СУММА([кол]*[цена]) в 1С: результат = 333 328 333 350 000, время = 547

* ИТОГ: подсчет в Си быстрее чем в 1С в 5,8 раз.

*———— ————————————- —————

Обратите внимание, что я работаю методами платформы с типами данных платформы и разница не на …%, а в …раз.

 

Сортируем..

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

1С:

Процедура СортироватьМассивВставкамиВозр(М)
перем колво;
перем к;
перем к_этот;
перем к_пред;
перем елмЭтот;
перем елмПред;
колво = М.Количество();
для к = 1 по колво - 1 цикл
к_этот = к;
пока к_этот >0цикл
к_пред = к_этот -1;
елмЭтот = М[к_этот];
елмПред = М[к_пред];
если елмЭтот < елмПред тогда
М[к_этот]= елмПред;
М[к_пред]= елмЭтот;
иначе
Прервать;
КонецЕсли;
к_этот = к_пред;
КонецЦикла;
КонецЦикла;
КонецПроцедуры

Си:

...
for(int i = 1; i < iSize; i++){
for(int j = i; j > 0; j--){
mValThis = pParaArrIArr->getAt(j);
mValPrev = pParaArrIArr->getAt(j - 1);
if( mValThis < mValPrev){
pParaArrIArr->setAt(j - 1, mValThis);
pParaArrIArr->setAt(j, mValPrev);
}
else{
break;
}
}
}
...

Для Си, конечно, несколько многословно, но я намеренно показываю, что код переносится чуть-ли не один в один.

 

С++:

...
v8com_array_iterator _First(pParaArrIArr, 0);
v8com_array_iterator _Last(pParaArrIArr, pParaArrIArr->size());
std::sort(_First, _Last);
...

 

1С с предикатом:

процедура СортироватьМассивВставкамиПред(М, Предикат)
перем колво;
перем к;
перем к_этот;
перем к_пред;
перем елмЭтот;
перем елмПред;
перем елмЭтотМеньшеПред;
колво = М.Количество();
для к =1по колво -1цикл
к_этот = к;
пока к_этот >0цикл
к_пред = к_этот -1;
елмЭтот = М[к_этот];
елмПред = М[к_пред];
выполнить("елмЭтотМеньшеПред = " + Предикат + "(елмЭтот, елмПред)");
если елмЭтотМеньшеПредтогда
М[к_этот]= елмПред;
М[к_пред]= елмЭтот;
иначе
Прервать;
КонецЕсли;
к_этот = к_пред;
КонецЦикла;
КонецЦикла;
КонецПроцедуры

В параметр предикат передаем «МодТест.СравнитьЗначенияНаМеньше»

Функция СравнитьЗначенияНаМеньше(знач знач1, знач знач2) экспорт
возврат ?(знач1 < знач2, истина, ложь);
КонецФункции

Для компоненты с предикатом посложнее… Делаем объект «Делегат»:

перем<делегат>;
<делегат> = <компонент>.СоздатьДелегат(<объект>[.ЭтотОбъект],“<имя-метода>”);
<делегат>.Вызвать(<список-параметров-метода>);

Т.е. создаем в компоненте объект инициализируемый ссылкой на объект (модуль) платформы и строкой с указанием, какой из методов (функций или процедур) вызвать с переданными при вызове параметрами. У этого объекта-делегата единственное назначение – передать параметры и управление в указанный метод объекта платформы (и вернуть результат, если это функция). Платформа не поддерживает конструкции вида <имя-переменной>(…), поэтому, после некоторых раздумий, я решил не фиксировать какой-либо определенный синтаксис. Делегат можно .Вызвать(…), .Выполнить(…), .Обработать(…), хоть .СделайМнеОоЛаЛа(…), в зависимости от семантики.

Процедура ТестДелегата()
сообщить("*---------- ТестДелегата -----------");
хДел = СПП.СоздатьДелегат(МодТест,"ТестДелегата_Функция");
хРез = хДел.Вызвать(202);
сообщить("* Делегат вызван, результат: " + хРез);
сообщить("*---------- ------------ -----------");
КонецПроцедуры
Функция ТестДелегата_Функция(пара)экспорт
сообщить("* вызов делегата, аргумент = "+ пара);
возврат пара +1;
КонецФункции

 

*———- ТестДелегата ————

* вызов делегата, аргумент = 202

* Делегат вызван, результат: 203

*———- ———— ————

 

С учетом этого код сортировки плюсами c предикатом выглядит как то так:

...
v8com_array_iterator _First(pParaArrIArr, 0);
v8com_array_iterator _Last(pParaArrIArr, pParaArrIArr->size());
v8com_compare_callback _Comp(pParaIDelegat);

std::sort(_First, _Last, _Comp);
...

 

Результаты:

*——————— сортировка массива ———————

*Количество элементов массива: 1 500          

*{802, 974, 846, 95, 355, 377, 933, 222, 968, 64, 198, 395, 966, …, 136, 611, 161}

* сортировка 1С  вставками, возр.  ==  3 078

* сортировка Си  вставками, возр.  ==    329

* сортировка С++ вставками, возр.  ==    235

* сортировка С++ std::sort, возр.  ==     17

* С++ std::sort с предикатом, возр. ==     94

* Си вставками с предикатом, возр. ==  2 064

* 1С  вставками с предикатом:       == 56 969

*

*Проверка массививов: ОК

*{1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, …, 992, 993, 994, 996, 996, 997, 997, 999}

*

* С вставками быстрее, чем 1С вставками в 9,4 раз

* С++ вставками быстрее, чем 1С вставками в 13,1 раз

* С вставками быстрее, чем С++ вставками в 0,7 раз

* С++ сорт быстрее, чем 1С вставками в 181,1 раз

* С++ сорт быстрее, чем С вставками в 19,4 раз

* С++ сорт быстрее, чем С++ вставками в 13,8 раз

* С++ сорт быстрее, чем С++ сорт с предикатом в 5,5 раз

* С++ сорт с предикатом быстрее, чем 1С сорт вставками в 32,7 раз

* С сорт вставками с предикатом быстрее, чем 1С сорт вставками в 1,5 раз

* 1С вставками с предикатом медленнее, чем 1С  сорт вставками в 18,5 раз

* 1С вставками с предикатом медленнее, чем Си  вставками с предикатом в 27,6 раз

* 1С вставками с предикатом медленнее, чем С++ сорт с предикатом в 606,1 раз

*——————— —————— ———————

Замечу, что количество элементов массива подобрано для получения некоторых характерных значений. Если их порядка 300, то с std::sort сравнить не получается – там просто 0. Если порядка 5000, то ждать пока 1С отсортирует с предикатом приходится неприемлемо долго. Графики в зависимости от количества элементов массива, конечно, были бы любопытны. Также интересно поведение std::_Insertion_sort(), влияние InterlockExhangeXXX, сравнение с контейнером над тривиальными типами данных, сравнение разных компиляторов, поведение в режиме отладки, т.д., т.п. При наличии времени и интереса это все, конечно, можно сделать.

Общие выводы:

1)      Любой алгоритм, перенесенный чуть ли не один в один из 1С в компоненту, оживляется на порядок. С теми же родными типами данных платформы и вычисленным собственным же АПИ платформы.

2)      Любой простенький алгоритм, написанный на языке 1С, несравнимо проигрывает вылизанному алгоритму из существующей С/С++ библиотеки, коих миллион.

 

Ну и в заключение, коль скоро у нас есть Делегат, можно похулиганить с полиморфизмом:

// Зоопарк делегатов
процедура ТестДелегатовЗоо()  экспорт
перем мойЗоопарк;
мойЗоопарк =новый Массив;
мойЗоопарк.Добавить(СоздатьСтруктуруЖивотное_Кошка("Мурка"));
мойЗоопарк.Добавить(СоздатьСтруктуруЖивотное_Собака("Шарик"));
ТестДелегатовЗоо_ОпроситьЗоопарк(мойЗоопарк);
КонецПроцедуры
Функция СоздатьСтруктуруЖивотное_Собака(Имя)
возврат СоздатьСтруктуруЖивотное(Имя, СоздатьДелегат(МодТест,"ЖивотноеСобака_Голос"));
КонецФункции
Функция СоздатьСтруктуруЖивотное_Кошка(Имя)
возврат СоздатьСтруктуруЖивотное(Имя, СоздатьДелегат(МодТест,"ЖивотноеКошка_Голос"));
КонецФункции
Функция СоздатьСтруктуруЖивотное(Имя, Голос)
возвратновый ФиксированнаяСтруктура("Имя, Голос", Имя, Голос);
конецфункции
Функция ЖивотноеКошка_Голос()           экспорт
возврат"Мяу";
КонецФункции
Функция ЖивотноеСобака_Голос()         экспорт
возврат"Гав";
КонецФункции
процедура ТестДелегатовЗоо_ОпроситьЗоопарк(З)
перем Ж;
сообщить("*");
сообщить("*------- Перекличка в зоопарке делегатов -----------");
длякаждого Ж из З цикл
Сообщить("* Животное '" + Ж.Имя + "' отозвалось '" + Ж.Голос.Вызвать() + "'");
КонецЦикла;
сообщить("*------- ------------------------------- -----------");
сообщить("*");
КонецПроцедуры

*——- Перекличка в зоопарке делегатов ————

* Животное ‘Мурка’ отозвалось ‘Мяу’

* Животное ‘Шарик’ отозвалось ‘Гав’

*——- ——————————- ————

 

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

//Зоопарк классов
функция ПолучитьОписательКлассаЖивотное()
перем К;
К = СоздатьОписательКласса("КлассЖивотное");
К.ДобавитьПоле("Имя");
К.ДобавитьПоле("м_ВремяРождения");
К.ДобавитьМетод("ДайВозраст", МодТест,"КлассЖивотное_ДайВозраст");
К.ДобавитьАбстрактныйМетод("ДайГолос");
возврат К;
КонецФункции
функция ПолучитьОписательКлассаЖивотноеКошка()
перем К;
К = ПолучитьОписательКлассаЖивотное();
К.ПереопределитьМетод("ДайГолос", МодТест,"КлассЖивотноеКошка_Голос");
возврат К;
КонецФункции
функция ПолучитьОписательКлассаЖивотноеСобака()
перем К;
К = ПолучитьОписательКлассаЖивотное();
К.ПереопределитьМетод("ДайГолос", МодТест,"КлассЖивотноеСобака_Голос");
возврат К;
КонецФункции
функция КонструкторЖивотного(Класс, Имя, ВремяРождения)
Класс.Имя = Имя;
Класс.м_ВремяРождения = ВремяРождения;
возврат Класс;
КонецФункции
функция СоздатьКлассЖивотное_Собака(Имя)
//туду: возврат ПолучитьОписательКласса("ЖивотноеСобака").Конструкторы[..].Вызвать(<список-параметров>);
//                     => .Вызвать(<класс-интерфейфейс-конструктора>, <параметры>)
возврат КонструкторЖивотного(СоздатьКлассПоОписателю(ПолучитьОписательКлассаЖивотноеСобака()), Имя, ДайТики()-456);
КонецФункции
функция СоздатьКлассЖивотное_Кошка(Имя)
возврат КонструкторЖивотного(СоздатьКлассПоОписателю(ПолучитьОписательКлассаЖивотноеКошка()), Имя, ДайТики()-567);
КонецФункции
функция КлассЖивотное_ДайВозраст(Класс, Еденицы)                               экспорт
перем х;
х = ДайТики()- Класс.м_ВремяРождения;
возврат Окр(?(Еденицы = ТипЕдиницыШкалыВремени.Минута, х/60, х),1);      //чё-то для теста
КонецФункции
функция КлассЖивотноеКошка_Голос(Класс)                                        экспорт
возврат"Мур-Мяу";
КонецФункции
функция КлассЖивотноеСобака_Голос(Класс)                                       экспорт
возврат"Гав-Гав";
КонецФункции
процедура ТестКлассовЗоо()  экспорт
перем мойЗоопарк;
мойЗоопарк =новый Массив;
мойЗоопарк.Добавить(СоздатьКлассЖивотное_Кошка("Мурка"));
мойЗоопарк.Добавить(СоздатьКлассЖивотное_Собака("Шарик"));
ТестКлассовЗоо_ОпроситьЗоопарк(мойЗоопарк);
КонецПроцедуры
процедура ТестКлассовЗоо_ОпроситьЗоопарк(З)
перем Ж;
сообщить("*");
сообщить("*------- Перекличка в зоопарке классов -----------");
длякаждого Ж из З цикл
Сообщить("* Животное '"+ Ж.Имя +"', возраст = "+ Ж.ДайВозраст(ТипЕдиницыШкалыВремени.Минута)+", отозвалось '"+ Ж.ДайГолос()+"'");
КонецЦикла;
сообщить("*------- ----------------------------- -----------");
сообщить("*");
КонецПроцедуры

*——- Перекличка в зоопарке классов ————

* Животное ‘Мурка’, возраст = 9,5, отозвалось ‘Мур-Мяу’

* Животное ‘Шарик’, возраст = 7,9, отозвалось ‘Гав-Гав’

*——- —————————— ————

 

 Пока все. Сыро, но работает. Возможности развития ограничиваются только фантазией. Примененимость повсеместная. Назрело поговорить. Масса вопросов, например, по синтаксису:

— о множественном наследовании думать или как все, кроме плюсов?

— и вообще Класс он НАСЛЕДУЕТСЯ ОТ ?, РАСШИРЯЕТ ?

— class <name> : private <base-class> — такое надо?

— this, me, self- как? В текущей реализации это просто переменная. Пишу Класс, будут конфликты можно переименовать. Но все же…

private — ЧАСТНЫЙ? ВНУТРЕННИЙ?

mustoverride – ПЕРЕОПРЕДЕЛЯЕМЫЙ ОБЯЗАТЕЛЬНО?

— …

И Особенно смущает вопрос, почему 1С это все скрывает, ведь все эти возможности есть у платформы с рождения.

У кого какие мысли?

 

Спасибо.

 

 

 

 <необходимое дополнение>

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

 

 

 

48 Comments

  1. baton_pk

    Ну, добро пожаловать в мир 1С. Не буду ругать и ставить минус, многие через ЭТО проходят на каком-то этапе освоения 1С. 🙂

    Reply
  2. JohnyDeath

    (1) А за что ругать?

    (0) Умеет наследоваться от классов-метаданных, например от Документ.ПриходныйКассовыйОрдер ?

    Reply
  3. script

    Дык а когда можно будет хоть что нибудь пощупать?

    Reply
  4. baton_pk

    (2) JohnyDeath,

    А за что ругать? 

    за то что, опять вот это вот: «язык 1С медленный», «язык 1С корявый» и тому подобные. и почему объектно-ориентироанная модель, а не прототипная, как в javascript?

    ещё и пощупать нечего 🙁

    Reply
  5. DitriX

    Просто в 1с — очень редко бывают случаи когда надо сделать то, о чем ваы говорите, в основном — такие объемы данных и расчеты выполнются на стороне SQL серверов, т.е. вытягиваются запросами.

    Вы немного путаете подходы. Это тоже самое, что и сравнивать разгон от 0 до 100 у болида и у полноценного джипа, т.е. — да, болид выйграет, тут вопросов нет, но вот только с нашими дорогами — эти сферические кони в вакууме (я о полученных цифрах) — даром не нужны.

    Как то так.

    Reply
  6. sorb

    (2) JohnyDeath, куча народу, начиная работать с 1С, идут в монастырь со своим уставом пытаются натянуть свои представления о том, как все должно быть устроено, вместо того, чтобы изучать местную методику разработки. Приведенные примеры — сферические кони, за которые в продакшне обычно увольняют. Сортировать массив — это круто, но знание существующих УКЗ в 1С позволит не заниматься такой ерундой. Перебирать строки для вычисления суммы? Ну как-бы это вообще с точки зрения 1С ошибка проектирования. Скомпилированный код выполняется быстрее интерпретируемого? Спасибо, кэп. Наследование? Давайте разбирать конкретные сценарии применения — обычно при обсуждении проблем с поддержкой и развитием больше, чем выгод.

    Ну и про отладку, обработку исключений тактично опущено, спишем на то, что пока речь о сырье.

    Но! При всех брошенных какашках замечаниях, автор — молодчина, именно из таких исследований иногда рождаются отличные инструменты.

    В общем, ругать не хочется, хочется следить за развитием событий 🙂

    Reply
  7. artbear

    Тема интересная, но без демки и/или кода выглядит слабовато.

    ЗЫ я занимался аналогичными проблемами в компоненте 1С++ для 1С 7.7 12 лет назад 🙂

    Reply
  8. fishca

    Все эти порядки, которые выигрываются кодом на С++, съедаются медленным получением данных из СУБД.

    Но смысл продолжать конечно есть, быстрая обработка никогда и никому еще не мешала.

    В идеале хотелось бы видеть 1С++ для 8.х.

    И да, даешь демку, хотя бы и сырую, будем высушивать общими усилиями.

    Reply
  9. Evil Beaver

    Ого как, 1С++ добрался и до восьмерки! Простите, но мы не узнаём вас в гриме… Откуда вы?

    Reply
  10. nSpirit2

    Ну все примеры хороши проблема в том что они совершенно не жизненны.

    Я не знаю как у остальных господ но у меня задачи сортировки массивов последний раз были в институте. В реальной разработке на 1с где большая часть данных получается запросами получение не сортированных данных из базы очень редкий случай.

    Но разработка несомненно очень интересная будем ждать того что можно пощупать

    Reply
  11. Evil Beaver

    Кстати, по существу:

    ООП в 1С — в чистом виде — не надо. Почему — дискутировали уже много, не буду повторяться.

    Но раз уж пошла такая пьянка, то:

    — о множественном наследовании думать или как все, кроме плюсов?

    Не надо. От такого отказались в яве, шарпе и остальных.

    — и вообще Класс он НАСЛЕДУЕТСЯ ОТ ?, РАСШИРЯЕТ ?

    Он НАСЛЕДУЕТ (но и РАСШИРЯЕТ тоже, почему нет)

    — class <name> : private <base-class> — такое надо?

    Зачееем??

    — this, me, self- как? В текущей реализации это просто переменная. Пишу Класс, будут конфликты можно переименовать. Но все же…

    У 1С-ников это называется «ЭтотОбъект»

    — private — ЧАСТНЫЙ? ВНУТРЕННИЙ?

    Зачем тащить синтаксис C++ в 1С? У 1С уже есть свои лексические конструкции для инкапсуляции.

    — mustoverride – ПЕРЕОПРЕДЕЛЯЕМЫЙ ОБЯЗАТЕЛЬНО

    Ваще сотона! не надо этого. Для начала дайте что-то пощупать, чтобы мы поняли о чем речь.

    А вообще — очень клево! Мы тут все любим всякие такие штуки, даже если они просто экспериментальные. Удачи вам!

    Reply
  12. Зеленоград

    Автор, вам плохо а медленном языке с русской нотацией и сложными объектами?

    Это ДРУГОЙ язык. Не для embedded, не для realtime — но для быстрого создания прототипов открытых учётных систем специалистом любой квалификации с большим количеством готового кода среднего качества с фрагментарной документацией.

    Reply
  13. nSpirit2

    (12) Зеленоград,

    фрагментарной документацией

    Хорошо что с этим потихоньку начали бороться 😀

    Reply
  14. BorovikSV

    (0) Автор а можете уточнить каков тип у переменных numTot, numQty,numPri? (Из первого примера на Си)

    А то как то представили кусок кода, скрыв самое интересное )

    Reply
  15. Evil Beaver

    Вброс:

    При подробном взгляде на ник автора посетила крамольная мысль.

    pITable->getValueAt(iRow, 1).getIValue()->getNumeric(numQty)

    Концептуально напоминает то, как сделано IValue в 1Script, только на C++. А не наблюдаем ли мы утечку информации о внутренностях платформы из недр конторы?

    Reply
  16. AlX0id

    (5) DitriX,

    А как же РАУЗ с миллионами операций? В общем-то, там бы сильно не помешало ускорить вычислительный процесс.. Вынести на SQL сложные запросы да еще и так, чтобы они там более-менее оптимально выполнялись — возможно далеко не всегда.

    А статье, конечно, не хватает «чего пощупать» )

    Reply
  17. kiruha

    Здорово конечно, но почему столько публикаций пытается оптимизировать код 1С, который в общих затратах на вывод отчета 0.5% ?

    Reply
  18. Gilev.Vyacheslav

    предлагаю автору сходить трудоустроиться в саму 1С, если талант, то дадут реализоваться, а если шапкозакидатель, то быстро всплывет….

    Reply
  19. Evil Beaver

    Не, ну чего вы накинулись на человека? Вдруг там действительно что-то интересное? Надо же счупать а потом уже обсуждать. Афтар — пешы есчо!

    Reply
  20. Evil Beaver

    (14) BorovikSV, ну судя по фрагменту кода, автор получил доступ к реализации объектов внутри 1С, например, к ТаблицеЗначений и IValue. И дергает похоже родную реализацию таких вещей, как getRowCount и IValue::getNumeric.

    Другое дело, непонятно зачем он пытается сравнивать скриптовый код и код на C++. Еще и цифры приводит. Можно подумать, кто-то сомневается, что машинный код быстрее….

    Reply
  21. BorovikSV

    (20) Evil Beaver,

    numTot += numQty * numPri;

    где там объектами пахнет? Просто умножение и сложение.

    Сдается мне что numTot, numQty,numPri имеют тип DOUBLE.

    Reply
  22. baton_pk

    (21) BorovikSV, может, у него операторы переопределены для Numeric-ов

    Reply
  23. Evil Beaver

    (22) baton_pk, он получает некий Numeric из «родного» IValue методом getNumeric. Я сильно подозреваю, что тип значения — это внутренний тип Number/Число, реализованный внутри платформы. С операторами тогда получается интереснее. Он не только нашел, где внутри dll перегружен operator*(V8Numeric,V8Numeric), но и прописал это объявление в своих *.h И сколько таких еще вещей нужно было раскопать и описать. Иными словами, там проделана немалая работа (если это не фейк). Хочется посмотреть.

    Reply
  24. Dach

    Будет реализация дополнительных плюшек к объекту Запрос, а особенно возможность управлять текстом, из которого запрос 1С трансформируется в запрос к СУБД?

    Хочется всех возможностей T-SQL, которых нет в 1С, например явного указания как делать джойн (nested loops, merge…)

    Reply
  25. BorovikSV

    (23) Evil Beaver,

    Некий getNumeric может называться и ExtractAsDouble, это ничего не меняет и не объясняет. Ведь мы не можем делать выводы о типах из названия метода.

    Сомневаюсь что человек перегружал арифметические операторы для встроенного некого гипотетического INumeric. На это указывает крайне скудное описание возможностей. Отсутствие демо.

    Ведь на кой черт заниматься «фантиками», если рабочего прототипа который можно показать еще нет?

    Пока все указывает на Double. Если так — то математика будет отличаться от 1С, которая использует длинную арифметику.

    Предположим, чисто гипотетически, что числа извлекаются как обертки (допустим INumeric) над родными длинными числами. Тогда придется вытаскивать и методы для реализации всевозможных операций над числами (их несколько десятков как минимум), а также нужно где то раздобыть указатели на фабрики этих самых чисел.

    Предположим что заголовки для INumeric уже имеются на 100%, и даже пусть это на 100% совпадает с заголовками у 1С.

    Так а дальше то что?

    Засунуть в отдельный поток вычисления — вряд ли возможно, ведь без патчинга платформы ты не заставишь ее синхронизироваться с тобой.

    Выполнять в том же потоке? подключить компоненту, откуда то вытащить модуль на VB (или C++) , на лету скомпилировать, запустить и если все прошло штатно сэкономить десяток другой миллисекунд?

    И первый же запрос к БД, нивелирует повышение производительности, которое досталось таким трудом.

    Я уж не говорю и том, что это хрен запустишь в продакшн, какие модуля на VB (C++) напишут средненькие 1С-ники, и наконец что случится при переходе на 8.4

    Reply
  26. Evil Beaver

    (25) BorovikSV, возможно и double, однозначных выводов сделать нельзя. Просто при взгляде на то, как вызывается API, мне кажется, что там платформенные numerics. Однако, если так, то получается, что автор должен был прописать все сигнатуры в h-файлах и каким-то образом залинковать их с платформой. А если там даже и double, то все равно pValueTable->getRowsCount() он обязан был где-то прописать, чтобы это компилировалось.

    Итого, у меня есть несколько вариантов:

    1. Найден способ доступа к API платформы, который позволяет сгенерировать еще и h-файлы классов.

    2. Этот код не реальный C++ код, а гипотетический. Никаких headers и вызовов в стиле pValueTable->getRowsCount() еще нет.

    3. Это вообще фейк

    4. Автор реально запилил все header-s для всех классов платформы. И не просто запилил, а нашел все перегруженные операторы и адреса реализаций внутри dll.

    4.1 Ник автора кажется мне очень любопытным.

    Reply
  27. IntelInside
    Reply
  28. Evil Beaver

    (27) Спасибо за ответы. Интересно. Ну про OneScript можете тереть свободно. baton_pk и я уже отметились в топике.

    Reply
  29. fishca

    (27) ничего не понял, но интригуешь классно, жду.

    Reply
  30. sorb

    (19) Evil Beaver, да никто его не обижает — лично я испытал энтузазим, идет бурление хомячков и волнения мозга, что и наблюдается по обилию взволнованных комментов 🙂

    Reply
  31. orefkov

    Проблемы дёргать методы объектов напрямую — давно уже нет.

    Что через IContext — универсальный 1Сный интерфейс, что у некоторых типов объектов (ТЗ, ДЗ и тп) — их спецефичными интерфейсами.

    Если в snegopat.reborn просмотреть внимательно папки engine и v8api — всё это найдётся и видно для пытливого ума.

    Однако автор рискует наступить на те же грабли, что и снегопат в свое время — релизозависимость от 1С.

    Достаточно 1С немного изменить интерфейсы, «потроха» объектов — и С++ный адаптер перестает работать, пока автор не отразит эти изменения.

    Как это было, когда 1С при переходе с 8.2 на 8.3 изменило внутренности своего объекта wstring, что сделать универсальный адаптер на С++ оказалось настолько сложно, что пришлось делать два отдельных snegopat.dll и snegopat83.dll.

    Вот к примеру «блуждания» прямого вызова «Предупреждения»:

    // Предупреждение
    #if ver >= 8.3.7
    21
    #elif ver >= 8.3.6
    20
    #elif ver >= 8.3.5
    19
    #else
    18
    #endif
    #if ver < 8.3
    save int messageBox(const v8string&in text, uint type=0, uint timeout=0, uint caption=0, HWND parent=uint(-1), mbp& param=mbp(), int i1=0, int i2=0, int i3=0)
    #else
    save int messageBox(const v8string&in text, uint type=0, uint timeout=0, uint caption=0, HWND parent=uint(-1), mbp& param=mbp(), int i1=0, int i2=0, int i3=0, int i4=0, int i5=0)
    #endif
    

    Показать

    от релиза к релизу меняется как номер виртуальной функции, так и сигнатура вызова.

    Возможно, то, что автор уже накопал — относительно стабильно, но это просто говорит о том, что накопано не так и много.

    Ну и самое главное — замеры сортировки вставками на С++ надо сравнивать не с реализацией этого алгоритма на 1С, а с тз.Сортировать();

    То есть использование этой компоненты для увеличения скорости работы — лукавство. Скорость работы интерпретатора 1С никогда не была «бутылочным горлышком», в которое упиралась производительность.

    Reply
  32. orefkov

    (23) Evil Beaver, ну, за Numeric могу сказать только то, что его внутренняя реализация не менялась с 7.7. Да-да, этот класс 1С полностью перетащила из 7.7 в 8ку, только название изменила с CNumeric на Numeric. Особо искать его методы не приходится — торчат наружу из core8x.dll. Пока автору просто — можно напрямую линковаться к core83.dll, так как 8.2 в списке поддерживаемых не значится. А в 8.4 возможно надо будет линковаться уже к core84.dll.

    Reply
  33. DrAku1a

    (0), Замерь производительность суммирования и сортировки на «Цикле в одну стоку«

    Reply
  34. IntelInside
    Reply
  35. bulpi

    1с этого не сделала, потому, что 97% 1с-ников не поняли НИЧЕГО из того, что Вы написали . И я среди них 🙂 А рынок 3% не формируют.

    Reply
  36. jan27

    (35) такое чувство, что вы этим гордитесь, не надо говорить за всех

    Reply
  37. fishca
    То что для нас по-приколу, для других «Обнаружена возможность исполнения неподписанного кода». Это закончится просто тем, что 1С прихлопнет лавочку удобным для нее способом и пойдем все читать Радченко v9

    Существует ведь 8.3z, так что если бы хотели прикрыть, то прикрыли давно.

    Reply
  38. nSpirit2

    (37) fishca, А откуда она 😀 Кажется Z версия есть только 8.2 платформы 8.3 не сертифицирована еще.

    (34)

    1С v9 с ООП, триггерами, с преферансом

    Вот это к сожалению очень мало вероятно. Я еще глупо надеюсь что 1с когда нибудь откажется от обратной совместимости с обычными формами.

    Reply
  39. IntelInside
    Reply
  40. shakmaev

    (27) (34) (39) Вы пишете:

    Наверно буду готовить, но я так тяжело пишу…

    Судя по длине и содержанию Ваших комментариев — писать Вам не так уж и тяжело. Так что ждем.

    Reply
  41. djam_arttek

    Очень интересно.

    Reply
  42. fjay69

    Из всего обсуждения я извлёк одну мысль: наступает момент, когда быстродействием кода приходится жертвовать в пользу читаемости кода. Перефразирую: можно написать очень быстрый код, но посторонний человек в нём ни черта не разберёт. Можно написать не очень быстрый код, но который легко сопровождается. Писать легко читаемый быстрый код дано только избранным.

    Reply
  43. IntelInside
    Reply
  44. brr

    (43) не пойдет создатель на контакт, во время 7.7 не шёл и сейчас не пойдет

    Reply
  45. IntelInside

    (44) brr,

    Спасибо. Я в общем и не рассчитывал (вру). Значит 1С STD не будет. Пространство для маневра сужается до 1С boost или dealwithfire.dll. Жду релиза.

    Reply
  46. logarifm

    Не ну отлично человек начал изучать 1С. Правда обычно это люди делают с другой стороны, ну вот он начала залазить с выхлопной трубы, начал классы переписывать.

    Reply
  47. info1i

    Давно эту статью прочел, возможность понравилась. Только тогда я еще тоже не знал, куда можно применить эту возможность. Но когда вспомнил про парсинг сайтов, регулярные выражения и сложные математические вычисления, то сразу вспомнил о необходимости использования не1Совского быстрого языка с мгновенным получением(записью) данных в 1С-базе. Думаю, использование этой связки будет лучшим способом решения сложных задач интеграции и математики.

    Reply
  48. baton_pk

    (0) прошу прощения, в этом деле есть подвижки??

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *