| 
    
            
         
         | 
    
  | 
Что лучше для .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; КонецЦикла; ТекстДок.Закрыть();  | 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |