Имя: Пароль:
1C
1С v8
более быстрый аналог значениеизстрокивнутр?
,
0 novichok79
 
16.10.18
10:59
Доброго времени суток, уважаемые специалисты.
Есть обработка, запускает кучу фоновых заданий, в фоновых используется сообщить для передачи данных, в сообщение кладется структура, полученная через ЗначениеВСтрокуВнутр, в главном фоновом задании эта структура собирается в данные и пишется дальше во внешние сервисы.
Основной затык по скорости - это непосредственно отправка во внешние сервисы и вызовы ЗначениеИзСтрокиВнутр. Есть ли что-то быстрее чем значениевстрокувнутр? заранее благодарю за ответы.
1 aleks_default
 
16.10.18
11:01
xdto
2 novichok79
 
16.10.18
11:02
(1) там же запись в xml потребуется, а это запись на диск, а это долго.
3 novichok79
 
16.10.18
11:05
цель - быстро переводить структуры с вложенными массивами в текст, сообщать этот текст основному фоновому заданию, в основном фоновом - перевести текст обратно в структуры.
4 arsik
 
гуру
16.10.18
11:05
(2) Зачем на диск? Xml и в памяти хорошо работает.
5 novichok79
 
16.10.18
11:06
(4) а можно пример кода сериализации и десериализации структуры?
6 hhhh
 
16.10.18
11:09
(5) общегоназначения.ЗначениеВСтрокуXML
    общегоназначения.ЗначениеИзСтрокиXML
7 Tonik992
 
16.10.18
11:19
(0) А сколько у вас по времени занимает операция ЗначениеВСтрокуВнутр ?
8 novichok79
 
16.10.18
11:31
(7) запущу замер производительности и скажу.
9 novichok79
 
16.10.18
11:35
(8) померяю скорость с ЗначениеВСтрокуXML, JSON, и отпишусь.
10 Tonik992
 
16.10.18
11:37
(8) И ЗначениеИзСтрокиВнутр() тоже интересно.

Я использую в своем решении эту пару функций. Проблем нет.
У вас большой объем данных сериализуется?
11 novichok79
 
16.10.18
11:40
(10) да, текстовые файлы JSON размером 90 кбайт, это запросы во внешний сервис
12 ptiz
 
16.10.18
11:48
Пихай свои структуры в ХранилищеЗначения со сжатием, а уже его - сериализуй.
13 Широкий
 
16.10.18
11:50
ЗначениеИзСтрокиВнутр - там ограничение по размеру как бы есть
14 novichok79
 
16.10.18
11:52
(13) интересно.
15 Вафель
 
16.10.18
11:52
а почему бы текстовые файлы не передавать как текст?
16 Вафель
 
16.10.18
11:52
зачем его сериализовать? это же и так текст
17 Вафель
 
16.10.18
11:53
+ можно пожать
18 Aceforg
 
16.10.18
11:57
(15) +1

ЗначениеВФайл самое быстрое.

структура из 30тыс элементов, размер файла 15 МБ, грузится за секунду. Быстрее не бывает
19 novichok79
 
16.10.18
12:00
(15) потому что текст, выводимый фоновым - это значениевстрокувнутр(структура), где структура - далее превращается в JSON и отправляется POST запросом в главном фоновом.
20 Вафель
 
16.10.18
12:01
(19) а как ты внутреннюю строку в жсон преобразуешь?
21 Tonik992
 
16.10.18
12:03
(19) Это ты таким образом с помощью Сообщить() в фоновом задании передаешь куда-то дальше данные, а потом  отлавливаешь сообщения эти где-то?
22 novichok79
 
16.10.18
12:03
(16) смысл ускорения фоновых и состоял в том, чтобы обращаться к файловой системе как можно меньше. поэтому используются сообщения фоновых заданий, которые висят в памяти процесса. потом сообщения фоновых заданий попадают в главный поток и преобразуются в наборы сообщений, которые собираются в один большой пакет и отправляются порционно во внешний сервис.
23 Вафель
 
16.10.18
12:09
те изначальный вопрос - как передать из одного фонового в другое значение
24 Вафель
 
16.10.18
12:11
сама 1с для таких целей использует

ПередаваемыйТекст = ОбщегоНазначения.ЗначениеВСтрокуXML(ПередаваемоеЗначение)
25 Вафель
 
16.10.18
12:12
ну и кроме сообщить способов нет (рпазве что сервер взаимодействия)
26 novichok79
 
16.10.18
12:16
(23) да
(24) я бы юзал JSON, он компактнее, чем XML. объем получившегося текста тоже влияет на скорость, верно?
27 novichok79
 
16.10.18
12:17
(25) еще есть хранилище общих настроек, но оно тормозное, т. к. есть обращение к БД, значит есть запись на диск.
28 Tonik992
 
16.10.18
12:23
(27) (26)
И все же хочу увидеться цифры, которые вы обещали
29 Tonik992
 
17.10.18
10:07
(8) Озвучить не сможете?
30 Cyberhawk
 
17.10.18
10:09
Откажись от сборщика-диспетчера
31 novichok79
 
17.10.18
10:26
(29) да, забыл, сейчас все будет.
32 novichok79
 
17.10.18
10:26
(30) в пользу чего?
33 novichok79
 
17.10.18
10:26
Тип сериализации = ЗначениеИзСтрокиВнутр
Кол-во итераций = 100
Дата начала = 10:25:37
Размер файла = 6 180 864 байт
Дата окончания = 10:26:25
Длительность в секундах = 00:00:48
Длительность в миллисекундах = 48263
34 novichok79
 
17.10.18
10:28
Тип сериализации = XML
Кол-во итераций = 100
Дата начала = 10:27:16
Размер файла = 6 180 864 байт
Дата окончания = 10:28:42
Длительность в секундах = 00:01:25
Длительность в миллисекундах = 85846
35 novichok79
 
17.10.18
10:30
Тип сериализации = JSON
Кол-во итераций = 100
Дата начала = 10:29:07
Размер файла = 6 180 864 байт
Дата окончания = 10:30:00
Длительность в секундах = 00:00:52
Длительность в миллисекундах = 52696
36 novichok79
 
17.10.18
10:30
ЗначениеВСтрокуВнутр < JSON < XML

как я и думал - количество текста тоже влияет
37 Tonik992
 
17.10.18
10:38
(36)
То есть даже ЗначениеВСтрокуВнутр оказался быстрее всех.
38 novichok79
 
17.10.18
10:41
(37) да.
39 novichok79
 
17.10.18
10:42
в целом, можно перейти на сериализацию в JSON, это стильно, модно, молодежно (с) всего 4 секунды разницы на 100 итераций.
40 Cyberhawk
 
17.10.18
10:49
(32) В пользу отсутствия всех сопутствующих телодвижений
41 тарам пам пам
 
17.10.18
10:52
Попробуй еще Fast Infoset, оно по идее должно быть быстрее json и xml.
42 novichok79
 
17.10.18
10:52
(40) и раскидать отправку данных во внешний сервис по фоновым заданиям?
43 arsik
 
гуру
17.10.18
11:08
(0) А как ты фоновое запускаешь?
44 PloAl
 
17.10.18
11:10
Судя по размеру файлов в (33), узкое место конкатенация.
В (27) большое заблуждение, что запись на диск медленная!
45 PloAl
 
17.10.18
11:11
пример:

&НаКлиенте
Процедура ДанныеМногоБуквПамять(Команда)
    ИтоговаяСтрока = "";
    ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
    Для Ит = 1 По 10000 Цикл
        ИтоговаяСтрока = ИтоговаяСтрока + "Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные" + Символы.ПС;
    КонецЦикла;
    ВремяВыполненияСек = (ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала) / 1000;
    Сообщить(ВремяВыполненияСек);
КонецПроцедуры

&НаКлиенте
Процедура ДанныеМногоБуквФайл(Команда)
    ИтоговаяСтрока = "";
    ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
    ЗТ = Новый ЗаписьТекста(ПолучитьИмяВременногоФайла());
    Для Ит = 1 По 10000 Цикл
        ЗТ.ЗаписатьСтроку("Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные");
    КонецЦикла;
    ВремяВыполненияСек = (ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала) / 1000;
    Сообщить(ВремяВыполненияСек);
КонецПроцедуры
46 novichok79
 
17.10.18
11:13
(45) результаты замеров в студию
47 Cyberhawk
 
17.10.18
11:14
(42) Да, пусть сами отправляют. Ну тебе там виднее, что да как, не спорю.
48 Cool_Profi
 
17.10.18
11:16
(46) На два порядка. Сам можешь проверить
49 Вафель
 
17.10.18
11:17
тепереча можно через массив строки складывать, без всяких записей текста
50 novichok79
 
17.10.18
11:17
(47) выполняется куча фоновых, у которых по 3 сообщения на поток. если каждое из них будет стучаться в сервис одновременно, сервис ляжет.
51 Cyberhawk
 
17.10.18
11:20
(50) Зачем тебе тогда о какой-то скорости диспетчера задумываться?
52 PloAl
 
17.10.18
11:24
(46)
8,531 первая процедура
0,039 вторая

При конкатенации выполняется поиск, замена символов экранирования, выделение памяти и.т.д.
53 Cyberhawk
 
17.10.18
11:28
(52) Вот это поворот ))
54 Вафель
 
17.10.18
11:29
(52) а через массив попробуй
55 novichok79
 
17.10.18
11:41
(54) +100500
56 novichok79
 
17.10.18
11:42
(51) объемы данных очень большие, поэтому хочется ускорить побольше проблемных мест.
57 novichok79
 
17.10.18
12:16
через Fast Infoset не все получается сериализовать, там по сути тот же XML будет, только укороченный, в этом случае выгоднее выглядит JSON.
58 H A D G E H O G s
 
17.10.18
12:21
Самым быстрым и простым у автора будет запись текста в файлы, без всяких сериализаций.
Еще более быстрым, но не простым будет передача через именнованные каналы.
59 Вафель
 
17.10.18
12:23
(58) там же не текст, а структуры
60 novichok79
 
17.10.18
12:30
(45) сравните вот это

Процедура ДанныеМногоБуквПамять(Команда)
    ИтоговаяСтрока = "";
    ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
    Аррайбля = Новый Массив;
    Для Ит = 1 По 10000 Цикл
        Аррайбля.Добавить("Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные");
    КонецЦикла;
    ИтоговаяСтрока = СтрСоединить(Аррайбля, Символы.ПС);
    ВремяВыполненияСек = (ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала) / 1000;
    Сообщить(ВремяВыполненияСек);
КонецПроцедуры

с этим

&НаКлиенте
Процедура ДанныеМногоБуквФайл(Команда)
    ИтоговаяСтрока = "";
    ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
    ЗТ = Новый ЗаписьТекста(ПолучитьИмяВременногоФайла());
    Для Ит = 1 По 10000 Цикл
        ЗТ.ЗаписатьСтроку("Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные, Тестовые данные");
    КонецЦикла;
    ВремяВыполненияСек = (ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала) / 1000;
    Сообщить(ВремяВыполненияСек);
КонецПроцедуры
61 novichok79
 
17.10.18
12:31
(58) пока самое быстрое - сериализация в значениевстроку, вывод в фоновом через сообщить и разбор в родительском фоновом через получитьсообщения()
62 H A D G E H O G s
 
17.10.18
12:32
(61) Есть же понимание, что это точно такая же запись в файл?
63 Borteg
 
17.10.18
12:32
Поток = Новый ПотокВПамяти();
    ЗаписьДанных = Новый ЗаписьДанных(Поток);
64 Cyberhawk
 
17.10.18
12:33
(57) FastInfoset еще и глючный
65 novichok79
 
17.10.18
12:34
(63) отлично, как я этот поток передам в другой сеанс?
66 H A D G E H O G s
 
17.10.18
12:36
(61) У вас внутри структур
"да, текстовые файлы JSON размером 90 кбайт, это запросы во внешний сервис"

Эти файлы сериализуются, сжимаются, пишутся в файл, читаются из файла, разжимаются, десериализуются в процессе передачи в фоновое.

Пишите в файл их сами, бес сериализации и смс, внутри структуры храните имя файла. И будет вам щасте.
67 Borteg
 
17.10.18
12:36
(65) Двоичные данные вернет поток при записи
68 Borteg
 
17.10.18
12:37
(67) ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные
69 Вафель
 
17.10.18
12:38
(68) а как двоичные данные передать?
70 Borteg
 
17.10.18
12:39
(69) через файл во временном хранилище, потом обратная операция файла в поток в памяти
71 Вафель
 
17.10.18
12:41
(70) ну так это нужно фоновое каждый раз завершать чтоб передать,а как бы затраты на создание не маленькие
72 novichok79
 
17.10.18
12:44
(70) ага, то от чего я уйти хочу + данные должны передаваться не по завершению дочернего фонового, а real-time. передать можно только через хранилище общих настроек, либо через сообщения пользакам. насколько я знаю, сеансовые данные и временное хранилище сбрасываются на диск, а сообщения пользаков хранятся в памяти rphosts. конечно rphosts тоже может часть памяти засвопить на диск, но у нас памяти то как раз хватает.
73 Вафель
 
17.10.18
12:45
(72) сделай рам диск )))
74 novichok79
 
17.10.18
12:47
(73) уже пробовал, медленно.
75 H A D G E H O G s
 
17.10.18
12:47
(72) "а сообщения пользаков хранятся в памяти rphosts"

Откуда такая инфа?
76 novichok79
 
17.10.18
12:58
(75) читал где-то, не помню уже. по скорости обмена между дочерним фоновым заданием и родительским - оно самое быстрое.
77 novichok79
 
17.10.18
13:09
по сути у меня всего 2 варианта - запись в хранилище настроек либо запись в сообщения пользаков.
запись в хранилище настроек даже дольше, чем запись элемента справочника - раз так, значит есть обращение к СУБД, а следовательно к диску. остаются сообщения пользаков, которые работают раз в 5 быстрее, насколько я помню по замерам производительности.
78 Cyberhawk
 
17.10.18
13:16
(75) Я ему это говорил
79 novichok79
 
17.10.18
13:17
(75) да, кстати, в моей же теме.
80 novichok79
 
17.10.18
13:18
81 PiotrLoginov
 
17.10.18
13:54
Может быть, пора уже резюмировать? Ничего быстрее, чем ЗначениеВСтроку/ИзСтроки нет. Тут предлагали именованные каналы, но это, наверное, немножко для другого.
Мое имхо - за универсальность надо платить. Если бы тип передаваемого значения был заранее определен, можно было бы еще что-то придумать. А так, когда мы сериализуем то одно, то другое, и это делает платформа, опираясь на свои знания об алгоритмах сериализации данных самых разных типов, приходится довольствоваться тем, что имеем.  Оно и так довольно шустро.
82 Borteg
 
17.10.18
13:55
(72) Используй Base64
Процедура ВФонеХерачимСтрокиВПоток() Экспорт
    
    Поток = Новый ПотокВПамяти();
    Для Г = 1 По 10 Цикл
        Для Н = 1 По 1000 Цикл
            ЗаписьДанных = Новый ЗаписьДанных(Поток);
            ЗаписьДанных.ЗаписатьСтроку("Строка данных");
            ЗаписьДанных.Закрыть();
        КонецЦикла;
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = Base64Строка(Поток.ЗакрытьИПолучитьДвоичныеДанные());
        Сообщение.Сообщить();
    КонецЦикла;
    
КонецПроцедуры


Процедура ВФонеПроверяемЧеНахерачили() Экспорт
    
    
    ЗаданиеМое = ФоновыеЗадания.Выполнить("ОбщийМодуль1.ВФонеХерачимСтрокиВПоток");
    
    Работает = Истина;
    Итерация = 0;
    ИмяФайла = "F:\New folder\1.txt";
    
    СообщениеПользователю = новый СообщениеПользователю;
    СообщениеПользователю.Текст = ИмяФайла;
    СообщениеПользователю.Сообщить();
    Пока Работает Цикл
        
        //ЗаданиеМое.ОжидатьЗавершения(2);
        
        МассивСообщений = ЗаданиеМое.ПолучитьСообщенияПользователю(Истина);
        
        Для Каждого СообщениеМое Из МассивСообщений Цикл
            ДвоичныеДанныеСтрока = Base64Значение(СообщениеМое.текст);
            
            //ПотокВПамяти = Новый ПотокВПамяти();
            //ЧтениеДаннных = Новый ЧтениеДанных(ДвоичныеДанныеСтрока);    

            ПотокВПамятиДляДвоичныхДанных = ДвоичныеДанныеСтрока.ОткрытьПотокДляЧтения();
            
            
            ЧтениеДанныхПотока = Новый ЧтениеДанных(ПотокВПамятиДляДвоичныхДанных);
            //
            //
            
            ДанныеПотока = ЧтениеДанныхПотока.Прочитать();
            
            ДД =   ДанныеПотока.ПолучитьДвоичныеДанные();
            
            ДвоичныеДанныеСтрока.Записать(ИмяФайла);
            
            Работает = Ложь;
        КонецЦикла;
        
        
        Итерация = Итерация +1;
        Если Итерация = 100 Тогда
            работает = ложь;
        КонецЕсли;
        
        
    КонецЦикла;
    
    
КонецПроцедуры
83 Borteg
 
17.10.18
13:56
(71) ну так двоичные данные через Base64 гуляют
84 Borteg
 
17.10.18
14:03
(82) Код немного кривоват, подправить надо где строки пишут.  А так работает, только что проверил на миллионе записей все передалось записалось.
85 Tonik992
 
17.10.18
14:10
(83) А как с памятью дела обстоят? 1С сама вычищает занятое пространство памяти объектом ПотокВПамяти?
86 Cyberhawk
 
17.10.18
14:20
(85) Ничо там не освобождается, т.к. оно попадает в сообщения пользователю. И они не то что после получения извне (с параметром удаления) не освобождают память, но и после завершения сеанса ФЗ ничего не освобождается.
87 Borteg
 
17.10.18
14:23
(86) замечу во время работы от 100000 записей очень сильно загружаются все ядра сервера. Память высвободилась сразу как запись произошла(у меня фоновое закончилось правда), не знаю насколько преобразование base64 быстрее чем то что было предложено выше, но файлами с системами внешними обмениваюсь спокойно, отчеты html разворачиваются мгновенно.
Я так и не понял почему нельзя из фоновых кидать сразу в сервис. Проблема именно в этом.
88 Cyberhawk
 
17.10.18
14:26
(87) Это у тебя где память высвобождается, в ФЗ внутри которого через Сообщить/СообщениеПользователю передаются большие строки?
89 Eiffil123
 
17.10.18
16:31
(21) похоже, что через метод ПолучитьСообщенияПользователю(). Я видел, как на этом методе делали вывод статусбара длительных операций: код выполнялся на сервере в фоновом задании и периодически через Сообщить возвращал процент выполнения, а на клиенте - периодически отпрашивал с помощью этого метода получал текущее состояние процесса. И это без всяких новомодных систем взаимодействия
90 Сияющий в темноте
 
17.10.18
21:17
Передача из одного процесса в другой через границу памяти очень медленная операция.
проверьте по замеру,что у вас тормозит именно сама передача.
и не забываем,что кадр окна памяти конечен,при передаче большого обьема данных один процесс рубит их по размерк окна(а не 64к ли там?),а другой на обратной стороне собирает.
91 Сияющий в темноте
 
17.10.18
21:23
А что если переписать обмен через внешнюю компоненту и асинхронное событие.Еще можнл сделать через Http сервисы,на которые обращаться через XmlHttpRequest и ожидать события получения данных,тогда будет более быстрая синхронизация.
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой