Вход | Регистрация

  1  2
1С:Предприятие :: 1С:Предприятие 8 общая

Механизмы платформенной сериализации

Механизмы платформенной сериализации
Я
   Tateossian
 
12.02.18 - 14:31
​Коллеги, всем привет! Это будет пост для размышления и обсуждения следующей проблемы. Мне не нравятся существующий стек технологий интеграции между 1С. Ни XML/JSON/свойTXT. Ни COM не нравится. Разве что веб-сервисы. Но интересуют именно коробочные, нативные решения. А вот почему. Я являюсь разработчиком на J2EE в нагрузку к 1С и там есть такая технология - встроенная сериализация в binary-формате. Почему 1С не сделает такой? Вот ежли брать классические текстовые форматы - они очень много весят. До упаковки в zip. И долго разбираются парсером. Каждый день ввиду специфики приходится грузить в базу 80Гб xml. Он грузится в 16 фоновых заданий и занимает процесс все равно около 1-1,5 часа. А вот такая проблема - я использую свою систему версионирования. Для хранения ссылок используется метод ЗначениеВСтрокуВнутр(); так как это поле нужно для поиска - оно индексируемое, а лимит на строковый индекс - 442 символа, а бывают отборы на 900 и более строк. Ок, для быстрого поиска я юзаю хэш-ключи, удобно многомерные сущности создавать, эти механизмы ускорили проведение расчета себестоимости с 30 до 5 минут. Но у хэша есть обратная проблема - из жэша нельзя получить искомые сущности. Так вот вопрос: как придумать свою компактную систему сериализации, чтобы быстро работала и весила не много. Может есть готовые советы. FastInfoSet не предлагать. Делал через поток в памяти скрестить с zip архиватором, но там не обойтись без вывода в файл, а нужен быстрый способ чтения/записи, без временных файлов. Какие есть варианты?
 
 
   Tateossian
 
101 - 12.02.18 - 17:03
(99) Смотри, в УПП какой кусок кода есть.
   Tateossian
 
102 - 12.02.18 - 17:07
(101)
Процедура РассчитатьСписаниеПоСредней(ТаблицаТоваров, ДатаНач, ДатаКон, СтруктураДопПараметров)
    
    // Основное допущение данного метода - игнорирование замкнутой цепочки перемещений между состояниями ("холостого хода"):

    // считаем, что если товар в ходе перемещений снова попал в исходное состояние, то он как бы не перемещался, 

    // это движение можно исключить из общего оборота, а стоимость движения принять равной 0. Цепочки перемещений 

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

    
    // Получим все состояния для товара, которые он принимал за период в виде таблицы

    //    ---------------------------------------------------------------------------------------------------------------------------------

    // |Состояние 1 (Источник) |Состояние 2 (Приемник)| Перемещаемое количество| Стоимость (нужна для упрощения последующей корректировки)

    
    // Последовательно обходя состояния, выделим контуры (пути, начала и концы которых совпадают)

    // В каждом контуре найдем количество, которое совершило перемещение по замкнутому кругу ("холостой ход"), 

    // и уменьшим каждое движение из контура на данное количество.

    // Будем выбирать другие состояния для получения всех контуров и применим к ним то же правило.

    
    // После нахождения контуров в графах перемещений и сокращения "холостого хода" получаем совокупность разомкнутых 

    // путей перехода товара между состояниями (остовные деревья). Внутри каждой такой цепочки выполняем расчет.

    // Важно:  в общем случае результат сокращения зависит от последовательности обхода контуров, поэтому

    // для повторяемости результата она должна подчиняться какому-либо правилу (например, чтобы сводные перемещения

    // упорядочивались по возрастанию даты первого перемещения)

    
    // Получим таблицу перемещений, содержащую суммарные перемещения между состояниями

    
    // Получаемая таблица должна содержать колонку "Количество", "Стоимость" и колонки, описывающие старое и новое состояние,

    // причем имена колонок нового состояния заканчиваются на ПрефиксПараметровНовогоСостояния

    ПрефиксПараметровНовогоСостояния="_НовоеСостояние";
    
    Таб = ПолучитьТаблицуПеремещений(ТаблицаТоваров, ДатаНач, ДатаКон, ПрефиксПараметровНовогоСостояния, СтруктураДопПараметров);
    
    СтруктураДопПараметров.Вставить("ТаблицаСписанныхПартийСпецодежды", ПолучитьСтруктруТаблицыСписанныхПартийСпецодежды(СтруктураДопПараметров.Учет));
    
    //1. Приведем переданную таблицу перемещений к требуемому виду:

    // Таблица имеет колонки Источник, Приемник, Количество

    // строка таблицы соответствует перемещению из состояния 1 в состояние 2, перемещения не повторяются.

    
    // Количество колонок без ПрефиксПараметровНовогоСостояния должно быть равно количеству колонок с ПрефиксПараметровНовогоСостояния

    // Сформируем также структуру, которая содержит параметры состояния товара

    СтруктураСостояния = Новый Структура;
    
    МассивСумм = Неопределено;
    СтруктураДопПараметров.Свойство("МассивСумм", МассивСумм);
    
    Если ТипЗнч(МассивСумм) <> Тип("Массив") Тогда
        МассивСумм = Новый Массив;
        МассивСумм.Добавить("Стоимость");
    КонецЕсли;
    
    
    // То же самое, но в соответствии - для удобства поиска

    СоотвСумм = Новый Соответствие;
    
    Для Каждого ЭлементСумм Из МассивСумм Цикл
        СоотвСумм.Вставить(ЭлементСумм, ЭлементСумм);
    КонецЦикла;
    
    Инд=0;
    Пока Инд< Таб.Колонки.Количество() Цикл
        
        Колонка = Таб.Колонки[Инд];
        
        // Имя колонки не совпадает с количеством и колонками стоимости

        Если ВРег(Колонка.Имя) <> ВРег("Количество") Тогда
            
            // Это колонка суммы

            Если СоотвСумм[Колонка.Имя] <> Неопределено Тогда
                Инд = Инд+1;
                Продолжить;
            КонецЕсли;
            
            // Колонки, оканчивающиеся на ПрефиксПараметровНовогоСостояния - правые (новое состояние), им должны соответствовать такие же левые, оканчивающиеся на ПрефиксПараметровНовогоСостояния

            Если Прав(Колонка.Имя, СтрДлина(ПрефиксПараметровНовогоСостояния)) = ПрефиксПараметровНовогоСостояния  Тогда
                ИмяСоответствующейКолонки=Лев(Колонка.Имя, СтрДлина(Колонка.Имя)-СтрДлина(ПрефиксПараметровНовогоСостояния));
                Если Таб.Колонки.Найти(ИмяСоответствующейКолонки)=Неопределено Тогда
                    Таб.Колонки.Добавить(ИмяСоответствующейКолонки, Колонка.ТипЗначения)
                КонецЕсли;
                // И наоборот, колонки, не оканчивающиеся на ПрефиксПараметровНовогоСостояния - левые (новое состояние), им должны соответствовать такие же правые, оканчивающиеся на ПрефиксПараметровНовогоСостояния

            Иначе
                ИмяСоответствующейКолонки=Колонка.Имя+ПрефиксПараметровНовогоСостояния;
                Если Таб.Колонки.Найти(ИмяСоответствующейКолонки)=Неопределено Тогда
                    Таб.Колонки.Добавить(ИмяСоответствующейКолонки, Колонка.ТипЗначения)
                КонецЕсли;
                
                СтруктураСостояния.Вставить(Колонка.Имя);
            КонецЕсли;
        КонецЕсли;
        
        Инд=Инд+1;
    КонецЦикла;
    
    // В таблице перемещений заменим параметры состояний индексами состояний, сами параметры будут храниться в СоотвПараметровСостояний

    
    //*15.01.2017 ******** 1456 { 

    //Таб.Колонки.Добавить("Источник", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9,0)));

    //Таб.Колонки.Добавить("Приемник", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9,0)));

    Таб.Колонки.Добавить("Источник", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9,0, ДопустимыйЗнак.Неотрицательный)));
    Таб.Колонки.Добавить("Приемник", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9,0, ДопустимыйЗнак.Неотрицательный)));
    //**15.01.2017 ******** 1456 } 


    СоотвПараметровСостояний = Новый Соответствие;
    
    //*15.01.2017 ******** 1456 {

    
    _СоотвПараметровСостояний = Новый Соответствие;
    _СоответствиеНумератор = Новый Соответствие;
    
    Для Каждого Строка Из Таб Цикл
        Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
        Для Каждого Элемент Из СтруктураСостояния Цикл
            Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда
                Продолжить;
            КонецЕсли;
            Если ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Строка[Элемент.Ключ])) Тогда
                Хеширование.Добавить(ИдентификаторСсылки(Строка[Элемент.Ключ]));
            Иначе                
                Хеширование.Добавить(XMLСтрока(Строка[Элемент.Ключ]));
            КонецЕсли;
        КонецЦикла;
        Хэш = Хеширование.ХешСумма;
        
        Если _СоотвПараметровСостояний.Получить(Хэш) = Неопределено Тогда
            ИндексСостояния = _СоотвПараметровСостояний.Количество();
            _СоответствиеНумератор.Вставить(Хэш, ИндексСостояния);
            _СоотвПараметровСостояний.Вставить(Хэш, Строка);
            СтрСост = Новый Структура;
            Для Каждого Элемент Из СтруктураСостояния Цикл
                Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда
                    Продолжить;
                КонецЕсли;
                СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ]);
            КонецЦикла;
            СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост);
        Иначе
            ИндексСостояния = _СоответствиеНумератор.Получить(Хэш);    
        КонецЕсли;
    
        Строка.Источник = ИндексСостояния;
        
        Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
        Для Каждого Элемент Из СтруктураСостояния Цикл
            Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда
                Продолжить;
            КонецЕсли;
            Если ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния])) Тогда
                Хеширование.Добавить(ИдентификаторСсылки(Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]));
            Иначе
                Хеширование.Добавить(XMLСтрока(Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]));
            КонецЕсли;
        КонецЦикла;
        Хэш = Хеширование.ХешСумма;
        
        Если _СоотвПараметровСостояний.Получить(Хэш) = Неопределено Тогда
            ИндексСостояния = _СоотвПараметровСостояний.Количество();
            _СоответствиеНумератор.Вставить(Хэш, ИндексСостояния);
            _СоотвПараметровСостояний.Вставить(Хэш, Строка);
            СтрСост = Новый Структура;
            Для Каждого Элемент Из СтруктураСостояния Цикл
                Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда
                    Продолжить;
                КонецЕсли;
                СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]);
            КонецЦикла;
            СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост);
        Иначе
            ИндексСостояния = _СоответствиеНумератор.Получить(Хэш);    
        КонецЕсли;
        
        Строка.Приемник = ИндексСостояния;
        
    КонецЦикла;
    
    //**15.01.2017 ******** 1456 } 

    
    ////Для Каждого Строка Из Таб Цикл // поиск выплняется полным перебором

    ////    

    ////    // Состояния-источники

    ////    // Найдем состояние в соответсвии                

    ////    НайденоСостояние=Ложь;

    ////    Для Каждого ЭлементСостояние Из СоотвПараметровСостояний Цикл

    ////        

    ////        НайденоСостояние=Истина;

    ////        Для Каждого Элемент Из СтруктураСостояния Цикл

    ////            

    ////            Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда

    ////                Продолжить;

    ////            КонецЕсли;

    ////            Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ]) Тогда

    ////                

    ////                НайденоСостояние = Ложь; // состояния различны

    ////                

    ////                Прервать; // дальше можно не проверять

    ////            КонецЕсли;

    ////        КонецЦикла;

    ////        

    ////        Если НайденоСостояние Тогда

    ////            Прервать;

    ////        КонецЕсли;

    ////    КонецЦикла;

    ////    

    ////    Если НайденоСостояние Тогда

    ////        ИндексСостояния = ЭлементСостояние.Ключ;

    ////    Иначе

    ////        // Переносим в соответствие

    ////        СтрСост = Новый Структура;

    ////        Для Каждого Элемент Из СтруктураСостояния Цикл

    ////            Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда

    ////                Продолжить;

    ////            КонецЕсли;

    ////            СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ]);

    ////        КонецЦикла;

    ////        

    ////        ИндексСостояния = СоотвПараметровСостояний.Количество();

    ////        СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост);

    ////    КонецЕсли;

    ////    

    ////    // Оставим в таблице ссылку на состояние

    ////    Строка.Источник = ИндексСостояния;

    ////    

    ////    

    ////    // То же самое для состояний-приемников

    ////    // Найдем состояние в соответсвии                

    ////    НайденоСостояние=Ложь;

    ////    Для Каждого ЭлементСостояние Из СоотвПараметровСостояний Цикл

    ////        

    ////        НайденоСостояние=Истина;

    ////        Для Каждого Элемент Из СтруктураСостояния Цикл

    ////            

    ////            Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда

    ////                Продолжить;

    ////            КонецЕсли;

    ////            

    ////            Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]) Тогда

    ////                

    ////                НайденоСостояние = Ложь; // состояния различны

    ////                

    ////                Прервать; // дальше можно не проверять

    ////            КонецЕсли;

    ////        КонецЦикла;

    ////        

    ////        Если НайденоСостояние Тогда

    ////            Прервать;

    ////        КонецЕсли;

    ////    КонецЦикла;

    ////    

    ////    Если НайденоСостояние Тогда

    ////        ИндексСостояния = ЭлементСостояние.Ключ;

    ////    Иначе

    ////        // Переносим в соответствие

    ////        СтрСост = Новый Структура;

    ////        Для Каждого Элемент Из СтруктураСостояния Цикл

    ////            СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]);

    ////        КонецЦикла;

    ////        

    ////        ИндексСостояния = СоотвПараметровСостояний.Количество();

    ////        СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост);

    ////    КонецЕсли;

    ////    

    ////    // Оставим в таблице ссылку на состояние

    ////    Строка.Приемник = ИндексСостояния;

    ////    

    ////КонецЦикла;

    
    // "Свернем" встречные перемещения: вместо двух перемещений типа 1->2 и 2->1 оставим одно 

    // с количеством |Кол12 - Кол21| в направлении большего перемещения.

    
    // Проведем следующее преобразование: повернем пары так, чтобы количество перемещения стало положительным

    Для Каждого Строка Из Таб Цикл
        
        Если Строка.Количество<0 Тогда
            Буф=Строка.Приемник;
            Строка.Приемник = Строка.Источник;
            Строка.Источник = Буф;
            Строка.Количество = - Строка.Количество;
            Для Каждого КолСумма Из МассивСумм Цикл
                Строка[КолСумма] = - Строка[КолСумма];
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
    
    // "Свертка" встречных перемещений

    Инд=0;
    КолВо = Таб.Количество();
    
    //*15.01.2017 ********  1456 {

    МИсточник = Новый ФиксированныйМассив(Таб.ВыгрузитьКолонку("Источник"));
    МПриемник = Новый ФиксированныйМассив(Таб.ВыгрузитьКолонку("Приемник"));
    МассивТаб = Новый Массив;
    Для Каждого Строка Из Таб Цикл
        МассивТаб.Вставить(Таб.Индекс(Строка), Строка);    
    КонецЦикла;
    ФиксМассив = Новый ФиксированныйМассив(МассивТаб);
    //**15.01.2017 ********1456 }

    
    Пока Инд<КолВо Цикл
        
        Строка = ФиксМассив[Инд];
        
        Инд2 = Инд+1;
        Пока Инд2<КолВо Цикл
            
            //*16.01.2017 ******** 1456 {

            Строка2 = ФиксМассив[Инд2]; 
            //Строка  = Таб[Инд];

            //**16.01.2017 ********1456 } 

            
            // Если найдено соответствующее встречное перемещение

            //*15.01.2017 ******** 1456 { 

            //Если Строка.Источник = Строка2.Приемник

            //    И Строка.Приемник = Строка2.Источник Тогда

            Если МИсточник[Инд] = МПриемник[Инд2] И МПриемник[Инд] = МИсточник[Инд2] Тогда
            //**15.01.2017 ******** 1456 } 

                
                Если Строка.Количество>Строка2.Количество Тогда
                    УменьшитьНаКоличество = Строка2.Количество;
                Иначе
                    УменьшитьНаКоличество = Строка.Количество;
                КонецЕсли;
                
                Строка.Количество  = Строка.Количество  - УменьшитьНаКоличество;
                Строка2.Количество = Строка2.Количество - УменьшитьНаКоличество;
                
                Для Каждого КолСумма Из МассивСумм Цикл
                    
                    Если Строка.Количество>Строка2.Количество Тогда
                        УменьшитьНаСтоимость = Строка2[КолСумма];
                    Иначе
                        УменьшитьНаСтоимость = Строка[КолСумма];
                    КонецЕсли;
                    
                    // То же самое - со стоимостью

                    Строка[КолСумма]  = Строка[КолСумма]  - УменьшитьНаСтоимость;
                    Строка2[КолСумма] = Строка2[КолСумма]  - УменьшитьНаСтоимость;
                КонецЦикла;
                
                // На этом обход можно прервать: быть не более одной пары встречных перемещений

                Прервать;
                
            Иначе
                Инд2 = Инд2+1;
            КонецЕсли;
            
        КонецЦикла; 
        
        Инд = Инд+1;
        
    КонецЦикла;
    
    // Удалим обнулившиеся строки

    // Удаляем только строки со всеми нулевыми суммами и нулевым количеством

    
    КолВо = Таб.Количество();
    Инд=0;
    Пока Инд<КолВо Цикл
        
        Строка  = Таб[Инд];
        
        НеНужноУдалять = Строка.Количество<>0;
        
        Если Не НеНужноУдалять Тогда
        
            Для Каждого КолСумма Из МассивСумм Цикл
                        
                НеНужноУдалять = НеНужноУдалять Или Строка[КолСумма]<>0;
                
            КонецЦикла;
        
        КонецЕсли;
        
        Если Не НеНужноУдалять Тогда
            Таб.Удалить(Строка);
            
            КолВо = КолВо-1;
        Иначе
            Инд=Инд+1;
        КонецЕсли;
        
    КонецЦикла;
    
    // Получили таблицу перемещений в требуемом формате

    ТаблицаПеремещений = Таб;    
    
    // Таблица перемещений содержит несколько несвязанных частей, относящихся к отдельным партиям - строкам таблицы ТаблицаТоваров

    
    // Обработка перемещений: разрыв контуров

    // Получим наборы смежных вершин для каждой вершины

    // Соотв СмежныеВершины Вершина, СмежныеВершины

    
    Источники = Новый Соответствие;
    Приемники = Новый Соответствие;
    МассивНачалДеревьев = Новый Массив;
    
    Для Каждого Строка Из ТаблицаПеремещений Цикл
        
        ПараметрыИсточника = Источники[Строка.Источник];
        Если ПараметрыИсточника = Неопределено Тогда
            СмежныеВершины= Новый Соответствие;
            ПараметрыИсточника = Новый Структура("Пройден, СмежныеВершины", Ложь, СмежныеВершины);
        КонецЕсли;
        
        ПараметрыИсточника.СмежныеВершины.Вставить(Строка.Приемник, ТаблицаПеремещений.Индекс(Строка));// во вложенной структуре храним смежную вершину и номер строки перемещения

        
        Источники.Вставить(Строка.Источник, ПараметрыИсточника);
        
    КонецЦикла;
    
    // Чтобы рассчитать перемещения, заменим каждый связный граф перемещений его остовным деревом

    // Для этого обойдем их все, найдем и разорвем все контуры по предложенному выше правилу.

    Для Каждого Элемент Из Источники Цикл
        Если НЕ Элемент.Значение.Пройден Тогда// если от вершины еще не строился контур, обрабатываем

            
            //ПройденныеВершины = Новый Соответствие;

            //НомерВершины = Элемент.Ключ;

            //ПройденныеВершины.Вставить(НомерВершины, -1);

            
            ПройденныеВершины = Новый ТаблицаЗначений;
            ПройденныеВершины.Колонки.Добавить("Ключ");
            ПройденныеВершины.Колонки.Добавить("Значение");
            
            НоваяСтрока = ПройденныеВершины.Добавить();
            НоваяСтрока.Ключ = Элемент.Ключ;
            НоваяСтрока.Значение = -1;
            
            НомерВершины = Элемент.Ключ;
            
            РазорватьКонтуры(НомерВершины, Источники, ПройденныеВершины, ТаблицаПеремещений);
        КонецЕсли;
    КонецЦикла;
    
    // После этого таблица содержит незамкнутую последовательность перемещений. 

    // Стоимость перемещений с количеством = 0 в таблице тоже должна быть приведена к 0.

    СтСумм = Новый Структура;// структура сумм

    
    Для Каждого Строка Из ТаблицаПеремещений Цикл
        
        Если Строка.Количество=0 Тогда
            
            Для Каждого КолСумма Из МассивСумм Цикл
                СтСумм.Вставить(КолСумма, -Строка[КолСумма]);
            КонецЦикла;
            
            ДобавитьЗаписиПоПеремещению(СоотвПараметровСостояний[Строка.Источник], СоотвПараметровСостояний[Строка.Приемник], СтСумм, СтруктураДопПараметров)
            
        Иначе
            
            Приемники.Вставить(Строка.Приемник, Строка.Приемник);
            
        КонецЕсли;
        
    КонецЦикла;
    
    // Теперь нужно выделить отдельные деревья, определить среднюю стоимость для каждого дерева, 

    // и начиная с самого начала каждого дерева последовательно рассчитать стоимость для каждого состояния/перемещения

    
    // Найдем начало каждого дерева - его нет в приемниках

    
    _СоответствиеНачал = Новый Соответствие;
    
    Для каждого Строка Из ТаблицаПеремещений Цикл
        
        // Анализируем только ненулевые дуги

        Если Строка.Количество<>0 Тогда
            
            // Если источника нет среди приемников, значит это начало дерева

            Если Приемники[Строка.Источник]=Неопределено Тогда
                
                //*16.01.2017 ******** 1456 {

                //ВершинаНайдена = Ложь; // признак того, что вершина уже есть в массиве

                // 

                //Для Каждого НачалоДерева Из МассивНачалДеревьев Цикл

                //    

                //    // Такая вершина уже имеется в списке начал

                //    Если Строка.Источник = НачалоДерева Тогда

                //        ВершинаНайдена = Истина;

                //        Прервать;

                //    КонецЕсли;

                //КонецЦикла;

                Если _СоответствиеНачал.Получить(Строка.Источник) = Неопределено Тогда
                    _СоответствиеНачал.Вставить(Строка.Источник);
                    МассивНачалДеревьев.Добавить(Строка.Источник);
                КонецЕсли;
                //**16.01.2017 ******** 1456 }

                
                
                //Если НЕ ВершинаНайдена Тогда

                //    МассивНачалДеревьев.Добавить(Строка.Источник);

                //КонецЕсли;

            
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    // На данном этапе нужна информация о начальном состоянии и внешнем поступлении в каждую вершину

    
    // Будем использовать список вершин, для каждой из которых указаны смежные вершины - приемники и 

    Вершины = Новый Соответствие;// здесь нам понадобится общее количество источников, приемники

    Для Каждого Строка Из ТаблицаПеремещений Цикл
        
        Если Строка.Количество=0 Тогда
            Продолжить;
        КонецЕсли;
        
        // Обработаем источник

        ПодчСтруктура = Вершины[Строка.Источник];
        Если ПодчСтруктура=Неопределено Тогда
            ПодчСтруктура = Новый Структура("КоличествоИсточников, Приемники, КоличествоРассчитанныхВходов", 0, Новый Соответствие, 0);
        КонецЕсли;
        
        СтСумм = Новый Структура;// структура сумм

        Для Каждого КолСумма Из МассивСумм Цикл
            СтСумм.Вставить(КолСумма, Строка[КолСумма]);
        КонецЦикла;
        
        ПодчСтруктура.Приемники.Вставить(Строка.Приемник, Новый Структура("Количество, СтруктураСумм", Строка.Количество, СтСумм));// Вместе с вершиной-приемником запоминаем количество перемещения

        
        Вершины.Вставить(Строка.Источник, ПодчСтруктура);
        
        // Обработаем приемник

        ПодчСтруктура = Вершины[Строка.Приемник];
        Если ПодчСтруктура=Неопределено Тогда
   Buster007
 
103 - 12.02.18 - 17:14
а, я подумал ты как-то ускорил решение СЛУ в запросе
   Вафель
 
104 - 12.02.18 - 17:15
Ну что зип архив помог?
   timurhv
 
105 - 12.02.18 - 17:22
(0) Нам интересно узнать постановку задачи, при которой необходимо загружать 80гб\день и перепроводить все.
И откуда эти 80гб берутся.
   Tateossian
 
106 - 12.02.18 - 17:27
(103) А, у тебя РАУЗ. Это для партионки. Но у меня есть dll считающая СЛУ. делал когда то. Могу сбросить, на x86 найти не могу, надо пересобирать. На x64 есть.

    ИмяВременногоФайла = КаталогВременныхФайлов() + "AddInGauss.dll";
    Макет = Документы.ъъРасчетСебестоимости.ПолучитьМакет("ВК_Гаусс");
    
    Макет.Записать(ИмяВременногоФайла);
    
    ПодключитьВнешнююКомпоненту(ИмяВременногоФайла, "VKGauss", ТипВнешнейКомпоненты.Native);
    ВнешКомп = Новый ("AddIn.VKGauss.AddInGaussExtension");
    
    МассивОтветов = Новый Массив(Разрядность);

    ВнешКомп.СоздатьМатрицу(Разрядность);
    
    Для Инд = 0 По Разрядность-1 Цикл
        Для Инд2 = 0 По Разрядность-1 Цикл
            ВнешКомп.УстановитьЗначение(Инд, Инд2, МатрицаКоэффициентов[Инд][Инд2]);
        КонецЦикла;
        ВнешКомп.УстановитьСвободныйЧлен(Инд, СтолбецПравыхЧастей[Инд]);
    КонецЦикла;
    
    ВнешКомп.РешитьУравнение();
    
    Для Инд = 0 По Разрядность-1 Цикл
        МассивОтветов[Инд] = ВнешКомп.ПолучитьЗначение(Инд);        
    КонецЦикла;
    
    Возврат МассивОтветов;
   Tateossian
 
107 - 12.02.18 - 17:27
(103) Заполняешь коэффициенты при неизвестных, столбец свободных членов и Решить().
   Tateossian
 
108 - 12.02.18 - 17:28
(105) Каждый день база должна быть перепроведена по партиям. В результате все перепроведенные регистры накопления выгружаются в такой вот документ.
   Вафель
 
109 - 12.02.18 - 17:28
гаусс - это же самый медленный способ
   Tateossian
 
110 - 12.02.18 - 17:30
(109) Он самый оптимальный. На cpp какая разница. Для 1С деление и обращение по индексу - это самые тяжелые операции во всем расчете(((
 
 Рекламное место пустует
   Tateossian
 
111 - 12.02.18 - 17:31
(104) Нет, так как нужно использовать его методы без создания файла.

(103) Куда мне выложить?
   Tateossian
 
112 - 12.02.18 - 17:36
Вот статейка насчет сериализации в JVM

htt ps:// habrahabr.r u/po st/60317/
   Buster007
 
113 - 12.02.18 - 17:36
(111) не, компонента не интересна ) В компоненте все в разы быстрее считается, можно даже не оптимизировать практически код, как есть перенести, и уже будет прирост производительности.
   Tateossian
 
114 - 12.02.18 - 17:39
(113) 1С не может в Bigdata и прочие Map&Reduce. Это приходится учитывать. Короче, не годится для сложных расчетных задач. А вообще все остальное в 1С прекрасно:)
   Tateossian
 
115 - 12.02.18 - 17:40
(113) Я не вижу ничего плохого усиливать 1С приданными силами и средствами. Особенно, когда посмотрел на устройство инструментов разработчика от ТормозИТ.
   Вафель
 
116 - 12.02.18 - 17:43
(111) Так на основании потока же можно
   Tateossian
 
117 - 12.02.18 - 17:45
(116) Напиши, плз, как. Я не смог завести, хоть и понимаю как работают потоки.
   Tateossian
 
118 - 12.02.18 - 17:47
(116) там видишь в чем проблема - вернуть ДД можно токлько в том случае, если создался ЗаписьZip файла не инициализированным. А чтобы передать объекту источник данных - можно только путь к файлу. То есть как бы он не асинхронный, этот метод. Может связку между чтением и записью зип...
   H A D G E H O G s
 
119 - 12.02.18 - 17:47
(116) Нет. В поток можно записать результат, но не получить исходные данные.
   H A D G E H O G s
 
120 - 12.02.18 - 17:48
Пишите в файл, чебынет?
   Tateossian
 
121 - 12.02.18 - 17:49
(119) Почему, поток двунаправленный. Все зависит от того, к чему его подсоединять - к чтению или записи. Тебе нужно только спозиционироваться на начальном байте и сделать флуш буферу.
   H A D G E H O G s
 
122 - 12.02.18 - 17:50
ррр, я сказал другими словами твою фразу в (118)
   Tateossian
 
123 - 12.02.18 - 17:52
(120) Да это очень дорогое удовольствие I/O операции... Для каждого чиха. У меня памяти много много оперативной:) Плюс ко всему кластер на диске 64Кб, представь, если писать однокилобайтные (хоть и временные) файлы...
   Вафель
 
124 - 12.02.18 - 17:55
напиши компоненту
   Tateossian
 
125 - 12.02.18 - 17:57
(124) Скорее всего так и будет...
   Вафель
 
126 - 12.02.18 - 18:00
можно кстати рам диск сделать и через него файлы гонять
   Tateossian
 
127 - 12.02.18 - 18:01
(126) У меня база sql там. Точнее, самые hiload таблички.
   Вафель
 
128 - 12.02.18 - 18:05
(127) я про (123)
   Tateossian
 
129 - 12.02.18 - 18:14
(128) Я могу так решить эту проблему, но дело в том, что вообще ищу универсальное решение, будь хоть я в пределах своего продакшн сервера, или хоть на своем компе. Так как это упростит лично мне работу во многих практических случаях.
   Вафель
 
130 - 12.02.18 - 18:15
(129) можно 7z или рар использовать, они могут без файлов
   Вафель
 
131 - 12.02.18 - 18:15
А на сасом деле ты выбрал не правильный механизм хранения ссылок
   Tateossian
 
132 - 12.02.18 - 18:16
(131) А как нужно было?
   Вафель
 
133 - 12.02.18 - 18:17
Откуда у тебя ссылки такие длинные? ты что талблицы значений приводишь к строкам?
 
 
   Tateossian
 
134 - 12.02.18 - 18:22
(133) Ключ записи регистра сведений без регистратора.
   Вафель
 
135 - 12.02.18 - 18:24
а как 1сники сделали в своем версионировании?
   Tateossian
 
136 - 12.02.18 - 18:31
(135) В хранилище лежат xml сериализованные, а измерение - ссылка на справочник или документ. Ссылка, понимаешь! А ее может не быть - удален документ, все, нет его:) Короче, не все задачи решает. В зазеркалье был пост, что они пилят платформенное версионирование. Вот это будет круто, но пока у меня даже еще конфа на совместимости:)
   lodger
 
137 - 12.02.18 - 18:34
(135) сериализуют. сперва это было в xml и через темп-файл, потом json.
теперь этот жсон можно не писать в файл. (с недавних версий).
   Вафель
 
138 - 12.02.18 - 18:36
(136) я предлагаю посмотреть как они сделали в платформе
   lodger
 
139 - 12.02.18 - 18:37
(136) "удален документ, все, нет его:)" - ну и прекрасно. ссылка превращается в текст равный её гуиду. в представлении данных остается представление полученное перед удалением.
объекта нет, а следы его существования и жизни - есть. потом .уки не отмажутся - "ой не было такого объекта, вам показалось..."
   Вафель
 
140 - 12.02.18 - 18:40
(139) основная проблема с регистрами, вот это я и предлагаю посмотреть в платформе. со ссылками проблемы нет
   Tateossian
 
141 - 12.02.18 - 18:49
Посмотрел в последней БСП. Там фастИнфо сет. И только ссылочные типы.

// Возвращает сериализованный объект в виде двоичных данных.

//
// Параметры:

//  Объект - Любой - сериализуемый объект.
//

// Возвращаемое значение:
//  ДвоичныеДанные - сериализованный объект.

Функция СериализоватьОбъект(Объект) Экспорт
    
    ЗаписьXML = Новый ЗаписьFastInfoset;
    ЗаписьXML.УстановитьДвоичныеДанные();
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    ЗаписатьXML(ЗаписьXML, Объект, НазначениеТипаXML.Явное);
    
    Возврат ЗаписьXML.Закрыть();

КонецФункции

Поиграл я с FastInfoSet:
ЗаписьXML = Новый ЗаписьFastInfoset;
ЗаписьXML.УстановитьДвоичныеДанные();
ЗаписьXML.ЗаписатьОбъявлениеXML();

ЗаписатьXML(ЗаписьXML, Объект, НазначениеТипаXML.Явное);

Р = ЗаписьXML.Закрыть();

РазмерДДВБайтах = Р.Размер();//172 байт   


Ы = ТиповыеОтчеты.СериализоватьОбъектXDTO(Объект); 

ДлинаОбычнойXMLСтроки = СтрДлина(Ы);  //242 символа


СтрокаДвДанных = ПолучитьHexСтрокуИзДвоичныхДанных(Р);//

ДлинаСтрокиДД = СтрДлина(СтрокаДвДанных);//344симв


Он действительно самый компактный формат. Но его потом записывают в хранилище. А вот если привести к строке - ровно в два раза увеличивается количество символов. А если в байтах - то 172 байтами строками хранятся в 688 байт.
   lodger
 
142 - 12.02.18 - 18:51
(141) а зачем дд в хекс в строку? дд записать не вариант?
   Tateossian
 
143 - 12.02.18 - 19:00
(142) А как ты запросом эти ДД искать будешь?
  1  2

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует