|
Что лучше для .csv? | ☑ | ||
---|---|---|---|---|
0
pessok
11.11.15
✎
16:11
|
Коллеги, привет! На стадии проектирования было решено, что некий массив данных для загрузки в другую систему будет выгружаться в .csv. В тот же момент было решено, что csv будет формироваться в текстовом документе с разделителями (ТекстовыйДокумент). Потом система выросла, пришла необходимость формировать сразу несколько разных массив данных (ну, скажем, по каждому складу, дабы не вдаваться в ненужные подробности).
Пока массив был один - все было прекрасно, сейчас их 5. Формируются они в разных потоках фоновыми заданиями. Запрос в каждом потоке выполняется секунд по 15-20 (в консоле 3-4 секунды), остальное время - около 15 минут записываются данные в ТекстовыйДокумент (порядка 25 тыщ строк по 100 символов). Система в этот момент глухо висит. Отсюда вопрос - как бы это дело оптимизировать. Пробовал формировать текст в обходе выборки и писать одной строкой в ЗаписьТекста - не улучшило ситуацию. Что еще можно попробовать прикрутить? Может табличный документ? |
|||
1
H A D G E H O G s
11.11.15
✎
16:12
|
Не формировать текст и писать построчно в ЗаписьТекста. Тема закрыта.
|
|||
2
Goggy
11.11.15
✎
16:15
|
(1) Ну у автора не получилось, как он уверяет...
|
|||
3
pessok
11.11.15
✎
16:17
|
(1) пробую
(2) я делал не как в (1), щас пробую |
|||
4
pessok
11.11.15
✎
16:29
|
ну, после (1) стало намного лучше. Пишет шустрее, виснет меньше, хотя все равно подвисает маленько.
H A D G E H O G s , спасибо! |
|||
5
pessok
11.11.15
✎
16:31
|
т.е., я правильно понимаю, что ТекстовыйДокумент.ДобавитьСтроку() пишет в раму, а ЗаписьТекста.ЗаписатьСтроку() сразу на диск? Таким образом рама не закакивается и система работает стабильнее?
|
|||
6
H A D G E H O G s
11.11.15
✎
16:33
|
(5) Нет.
|
|||
7
pessok
11.11.15
✎
16:34
|
(6) ну так расскажи, не жадничай
|
|||
8
pessok
11.11.15
✎
16:35
|
з.ы. сейчас все сформировалось за 8 минут и тупило значительно меньше.
|
|||
9
H A D G E H O G s
11.11.15
✎
16:35
|
"Рама" не может закакиваться. Ее может не хватать, она может быть фрагментирована. Но в твоем случае идет постоянная реаллокация под все большую непрерывную в памяти строку все медленнее и медленнее. Запись на диск тупо скидывает в кэш диска без реаллокации. Щасте.
|
|||
10
H A D G E H O G s
11.11.15
✎
16:36
|
(8) Все равно медленно.
|
|||
11
pessok
11.11.15
✎
16:36
|
(9) ну да, "закакивается" - я имел ввиду, что отжирается. Спасибо!
|
|||
12
pessok
11.11.15
✎
16:38
|
(10) да там само формирование пришлось делать неадекватное.
Я бы даже вполне трезво назвал это gовнокодом... ТекстДок = Новый ЗаписьТекста(ПутьВременногоФайла, КодировкаТекста.UTF8); Разделитель = ?(НовыйВариант, ",", "#"); Колонки = РезультатЗапроса.Колонки; КоличествоКолонок = Колонки.Количество()-1; //Формируем заголовок ТекстЗаголовок = "pp, c1_code, product_code, category, brand, name, quantity_free, quantity_free_all, price_last, price_min, moic, sell_date"; МассивКолонокДляВыгрузки = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ТекстЗаголовок); ТекстДок.ЗаписатьСтроку(ТекстЗаголовок); Пока Выборка.Следующий() Цикл ТекстСтроки = ""; Для Каждого КолонкаПроверки Из МассивКолонокДляВыгрузки Цикл Колонка = СокрЛП(КолонкаПроверки); Если Колонки.Найти(Колонка) <> Неопределено Тогда ЗначениеЗаполнения = Выборка[Колонка]; Если ТипЗнч(ЗначениеЗаполнения) = Тип("Число") Тогда ЗначениеЗаполнения = Формат(ЗначениеЗаполнения, "ЧДЦ=; ЧРД=.; ЧН=0; ЧГ=0"); Иначе Если НовыйВариант Тогда ЗначениеЗаполнения = СтрЗаменить(ЗначениеЗаполнения, ",", "#"); ЗначениеЗаполнения = СтрЗаменить(ЗначениеЗаполнения, """", "^"); КонецЕсли; КонецЕсли; Иначе Если Колонка = "category" Тогда ПолноеНаименование = ?(НовыйВариант, СтрЗаменить(СтрЗаменить(Выборка.Ссылка.ПолноеНаименование(), ",", "#"), """", "^"), Выборка.Ссылка.ПолноеНаименование()); Наименование = ?(НовыйВариант, СтрЗаменить(СтрЗаменить(Выборка.Наименование, ",", "#"), """", "^"), Выборка.Наименование); ЗначениеЗаполнения = СтрЗаменить(ПолноеНаименование, "/"+Наименование, ""); КонецЕсли; КонецЕсли; ТекстСтроки = ТекстСтроки + ЗначениеЗаполнения + Разделитель; КонецЦикла; ТекстСтроки = Лев(ТекстСтроки, СтрДлина(ТекстСтроки)-1); ТекстДок.ЗаписатьСтроку(ТекстСтроки); ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Обработано "+Инд+" из "+КоличествоЗаписей); Инд=Инд+1; КонецЦикла; ТекстДок.Закрыть(); |
|||
13
H A D G E H O G s
11.11.15
✎
16:40
|
Выборка.Ссылка.ПолноеНаименование()
убрать в запрос |
|||
14
H A D G E H O G s
11.11.15
✎
16:40
|
Инд=Инд+1;
заменить хотябы на целочисленно на 1000 деление |
|||
15
pessok
11.11.15
✎
16:44
|
(13) в что, появился нормальный способ полное наименование формировать в запросе?
с индикатором согласен, сделаю вывод раз в 1000 |
|||
16
Serginio1
11.11.15
✎
16:46
|
||||
17
pessok
11.11.15
✎
16:47
|
+(15) просто если это можно нормально сделать в запросе, то можно будет полностью уйти от цикла по колонкам
|
|||
18
H A D G E H O G s
11.11.15
✎
16:48
|
(17) Ну хотя бы кэш сделай.
|
|||
19
H A D G E H O G s
11.11.15
✎
16:48
|
Это же жесть
|
|||
20
Лодырь
11.11.15
✎
16:48
|
(15) А какой у тебя принцип формирования полного наименования?
|
|||
21
Serginio1
11.11.15
✎
16:49
|
Плюс используй для формирования не текстовый документ а ЗаписьТекста или ЗаписьXML.ЗаписатьБезОбработки http://speshuric.livejournal.com/163665.html
|
|||
22
pessok
11.11.15
✎
16:53
|
(18) а поможет ли? у меня для каждого массива данных своя номенклатура, т.е. все равно в фоне нужно будет формировать для каждого
(19) однозначно жесть... (20) платформенная функция (15), (21) это уже мы порешали :) в данный момент идет разбор именно код формирования строки |
|||
23
pessok
11.11.15
✎
16:54
|
(22) хотя... можно ведь сформировать один раз для всей номенклатуры кеш и отдать уже его каждому фоновому заданию, все равно быстрее будет
|
|||
24
Serginio1
11.11.15
✎
16:56
|
Для чисел используй XMLСтрока
|
|||
25
Timon1405
11.11.15
✎
16:56
|
(22) Разве нельзя сделать реквизит номенклатуры "ПлатформенноеПолноеНаименование" и ПриЗаписи номенклатуры формировать его?
|
|||
26
pessok
11.11.15
✎
16:58
|
(25) можно, конечно, но это как-то, на мой вкус, так себе выход. С кешем нравится больше
|
|||
27
pessok
11.11.15
✎
16:58
|
(24) попробую, мерси
|
|||
28
pessok
11.11.15
✎
17:23
|
в итоге таки да
сначала формируем кеш полных наименований (соответствие) - около минуты передаем его фоновому заданию, оно уже записывает в файл влет, что-то тоже около минуты. это с учетом XMLСтрока вместо Формат Всем спасибо! |
|||
29
H A D G E H O G s
11.11.15
✎
17:39
|
Медленно
|
|||
30
pessok
11.11.15
✎
18:08
|
(29) ну как еще ускорить - я уже хз
РезультатЗапроса = Запрос.Выполнить(); Выборка = РезультатЗапроса.Выбрать(); КоличествоЗаписей = Выборка.Количество(); Инд = 0; ИмяФайла = ?(НовыйВариант, "new_", "")+Строка(ТорговаяТочка.Наименование)+".csv"; ПутьВременногоФайла = КаталогВременныхФайлов()+ИмяФайла; ТекстДок = Новый ЗаписьТекста(ПутьВременногоФайла, КодировкаТекста.UTF8); Разделитель = ?(НовыйВариант, ",", "#"); Колонки = РезультатЗапроса.Колонки; КоличествоКолонок = Колонки.Количество()-1; //Формируем заголовок ТекстЗаголовок = "pp, c1_code, product_code, category, brand, name, quantity_free, quantity_free_all, price_last, price_min, moic, sell_date"; МассивКолонокДляВыгрузки = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ТекстЗаголовок); ТекстДок.ЗаписатьСтроку(ТекстЗаголовок); Пока Выборка.Следующий() Цикл ТекстСтроки = ""; Для Каждого КолонкаПроверки Из МассивКолонокДляВыгрузки Цикл Колонка = СокрЛП(КолонкаПроверки); Если Колонки.Найти(Колонка) <> Неопределено Тогда ЗначениеЗаполнения = Выборка[Колонка]; Если ТипЗнч(ЗначениеЗаполнения) = Тип("Число") Тогда //ЗначениеЗаполнения = Формат(ЗначениеЗаполнения, "ЧДЦ=; ЧРД=.; ЧН=0; ЧГ=0"); ЗначениеЗаполнения = XMLСтрока(ЗначениеЗаполнения); Иначе Если НовыйВариант Тогда ЗначениеЗаполнения = СтрЗаменить(ЗначениеЗаполнения, ",", "#"); ЗначениеЗаполнения = СтрЗаменить(ЗначениеЗаполнения, """", "^"); КонецЕсли; КонецЕсли; Иначе Если Колонка = "category" Тогда ПолноеНаименованиеИзКеша = КешПолныхНаименований[Выборка.Ссылка]; ПолноеНаименование = ?(НовыйВариант, СтрЗаменить(СтрЗаменить(ПолноеНаименованиеИзКеша, ",", "#"), """", "^"), ПолноеНаименованиеИзКеша); Наименование = ?(НовыйВариант, СтрЗаменить(СтрЗаменить(Выборка.Наименование, ",", "#"), """", "^"), Выборка.Наименование); ЗначениеЗаполнения = СтрЗаменить(ПолноеНаименование, "/"+Наименование, ""); КонецЕсли; КонецЕсли; ТекстСтроки = ТекстСтроки + ЗначениеЗаполнения + Разделитель; КонецЦикла; ТекстСтроки = Лев(ТекстСтроки, СтрДлина(ТекстСтроки)-1); ТекстДок.ЗаписатьСтроку(ТекстСтроки); Если Инд%100 = 0 Тогда ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Обработано "+Инд+" из "+КоличествоЗаписей); КонецЕсли; Инд=Инд+1; КонецЦикла; ТекстДок.Закрыть(); |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |