|   |   | 
| 
 | Посоветуйте как можно ускорить обработку больших файлов (MXL) | ☑ | ||
|---|---|---|---|---|
| 0
    
        Михаил Козлов 22.10.18✎ 10:31 | 
        Платформа: 8.3.12 64 бита.
 Конфигурация: "пустая". Есть: 16 файлов MXL размером 0,6-1,1 Гб. - данные о продажах по дням месяца (1 файл - 2 дня) некоей группы товаров некоего ритейлера. Нужно: собрать данные и сохранить их в виде, доступном для дальнейшей обработки в Экселе. Как делал: простенькая обработка: - чтение файла MXL в табличный документ; - формирование таблицы значений (обходом табличного документа); - свертка таблицы значений; - сохранение в CSV через ЗаписьТекста частями (ограничение Эксель на число строк). Формирование таблицы значений примерно часов 12-14. Результирующая таблица примерно 11 400 000 строк. Запись в CSV шла больше суток. 12 файлов примерно по 90 Мб. Возможно, из-за того, что на сервере еще кое-что делалось. | |||
| 1
    
        Cool_Profi 22.10.18✎ 10:33 | 
        90 МБ в цсв? Это какого радиуса руки надо иметь?     | |||
| 2
    
        Fragster гуру 22.10.18✎ 10:37 | 
        вот именно "сохранение в CSV через ЗаписьТекста" больше суток? это очень, очень странно. может все-таки будет код?     | |||
| 3
    
        RomanYS 22.10.18✎ 10:40 | 
        (2) +1
 Проблема явно не в ЗаписьТекста. | |||
| 4
    
        Михаил Козлов 22.10.18✎ 10:40 | 
        (2) Процедура ЗаписатьТаблицуВФайлыCSV()
 разд = ";"; числоСтрок = данные.Количество(); запись = Новый ЗаписьТекста; часть = 1; имяФайла = Каталог+"\МАГНИТ_"+СТРОКА(часть)+".CSV"; запись.Открыть(имяФайла, КодировкаТекста.ANSI); записано = 0; конСтрока = данные.Количество(); ЭлементыФормы.Индикатор.МаксимальноеЗначение = конСтрока/1000; Индикатор = 0; ДЛЯ инд = 1 ПО конСтрока Цикл Если инд=Цел(инд/1000)*1000 Тогда Индикатор = Индикатор + 1; КонецЕсли; Если записано>=числоСтрокCSV Тогда запись.Закрыть(); часть = часть + 1; имяФайла = Каталог+имяСети+СТРОКА(часть)+".CSV"; запись.Открыть(имяФайла, КодировкаТекста.ANSI); записано = 0; КонецЕсли; текСтр = данные.Получить(инд-1); стр = текСтр.Номенклатура+разд+текСтр.Магазин+разд+текСтр.кодПодразделения+разд+текСтр.Количество+разд+текСтр.Сумма+разд; запись.ЗаписатьСтроку(стр); записано = записано + 1; КонецЦикла; запись.Закрыть(); КонецПроцедуры | |||
| 5
    
        Fragster гуру 22.10.18✎ 10:41 | 
        текСтр.ХХХ - это строки?     | |||
| 6
    
        assasu 22.10.18✎ 10:42 | 
        текСтр = данные.Получить(инд-1);
 тут трабла. может выполняться очень долго в большой таблице | |||
| 7
    
        Михаил Козлов 22.10.18✎ 10:42 | 
        (5) Да, это строка таблицы значений.     | |||
| 8
    
        Михаил Козлов 22.10.18✎ 10:43 | 
        (6) А как иначе?     | |||
| 9
    
        Cool_Profi 22.10.18✎ 10:43 | 
        Сын из слов отца, купившего Ладу Калину, знал только слово "колотить"...     | |||
| 10
    
        assasu 22.10.18✎ 10:44 | 
        (8) индексирование нужно по таблице. и поиск по индексу. так быстрее     | |||
| 11
    
        assasu 22.10.18✎ 10:45 | 
        (10) +  либо алгоритм переделать. не перебирать числа и по числам искать строки , а сразу перебирать строки     | |||
| 12
    
        Fragster гуру 22.10.18✎ 10:46 | 
        (7) я про тип значения колонок     | |||
| 13
    
        Fragster гуру 22.10.18✎ 10:47 | 
        ну и вместо конкатенации через плюс лучше делать ЗаписьТекста.Записать а последним куском ЗаписатьСтроку()     | |||
| 14
    
        Михаил Козлов 22.10.18✎ 10:48 | 
        (10) Не понял, какой поиск по индексу: номер строки - переменная цикла.
 (11) Никакие строки не ищу: получаю строку по номеру. Или я чего-то не понимаю? (12) Типы значения колонок - строка. (13) Принято. | |||
| 15
    
        Fragster гуру 22.10.18✎ 10:48 | 
        и индикатор обновляй раз в 1000 строк, а не каждую строку... сразу не увидел, блин     | |||
| 16
    
        VladZ 22.10.18✎ 10:49 | 
        (0) сохранение в CSV через ЗаписьТекста частями (ограничение Эксель на число строк). - Поставь нормальную версию Эксель. Там нет никаких ограничений. Открывай файл MXL и сохраняй как XLS.     | |||
| 17
    
        Fragster гуру 22.10.18✎ 10:49 | 
        инд=Цел(инд/1000)*1000
 -> инд % 1000 = 0 | |||
| 18
    
        assasu 22.10.18✎ 10:50 | 
        (14) получение строки по номеру тот же поиск .     | |||
| 19
    
        Fragster гуру 22.10.18✎ 10:50 | 
        (17)+ блин, кто так пишет, да еще и в одну строку. чтобы глаза сломать?     | |||
| 20
    
        Fragster гуру 22.10.18✎ 10:51 | 
        (18) не совсем. но замер производительности ответил бы на многие вопросы.     | |||
| 21
    
        aleks_default 22.10.18✎ 10:51 | 
        (18)Зачем он вообще здесь нужен? Для каждого Текстрока из данные нельзя?     | |||
| 22
    
        assasu 22.10.18✎ 10:52 | 
        (20)да     | |||
| 23
    
        Tonik992 22.10.18✎ 10:52 | 
        (6) Ага.
 Попробуйте вместо таблицы значений использовать Массив + Структура (значение каждого элемента). http://catalog.mista.ru/public/79285/ Здесь сравнение некоторых универсальных коллекций по скорости | |||
| 24
    
        RomanYS 22.10.18✎ 10:53 | 
        (14) блин, а сделать замер нельзя? Сразу будет видно какая из 3х строк тормозит     | |||
| 25
    
        Fragster гуру 22.10.18✎ 10:54 | 
        (23) а сворачивать данные ты как будешь? кодом?     | |||
| 26
    
        Михаил Козлов 22.10.18✎ 10:54 | 
        (13) Вместо конкатенации записывать каждое значение и записывать разделитель?
 (15) Индикатор обновляется для каждой 1000. (17) Принято. (16) 2^20 (21) Принято. (23) Заполнение таблицы гораздо быстрее записи в CSV. Нужно делать свертку по магазинам и товарам. | |||
| 27
    
        Михаил Козлов 22.10.18✎ 10:59 | 
        (24) Вот и спрашиваю: запись 1 000 000 строк CSV - 2,5-3 часа это нормально или нет? 
 Может причина в занятости диска (SSD). К сожалению, не могу запустить в "одиночестве" на сервере. | |||
| 28
    
        Fragster гуру 22.10.18✎ 11:01 | 
        кстати, можно попробовать вместо ЗаписьТекста ТекствыйДокумент     | |||
| 29
    
        RomanYS 22.10.18✎ 11:02 | 
        (28) не, там точно тормознее     | |||
| 30
    
        VladZ 22.10.18✎ 11:03 | 
        (26) Что значит 2^20?     | |||
| 31
    
        Fragster гуру 22.10.18✎ 11:03 | 
        (29) ну тут хз. может записьтекста в диск срет каждый "записать". Хотя по моим ощущениям самый быстрый - это ЗаписьXML и ЗаписатьБезОбработки     | |||
| 32
    
        Fragster гуру 22.10.18✎ 11:04 | 
        в любом случае без замеров можно долго гадать     | |||
| 33
    
        Михаил Козлов 22.10.18✎ 11:05 | 
        (26) Ограничение на число строк на листе в Эксель.     | |||
| 34
    
        Вафель 22.10.18✎ 11:06 | 
        может строку сформировать большую через массив, а потом ее разом записать?     | |||
| 35
    
        Fragster гуру 22.10.18✎ 11:08 | 
        (34) создание строк через + тормозит, особенно больших. проведи эксперимент, попробуй сделать строку из миллиона пробелов через "+"     | |||
| 36
    
        Вафель 22.10.18✎ 11:10 | 
        (35) читай внимательно: через массив     | |||
| 37
    
        VladZ 22.10.18✎ 11:12 | 
        (33) И вы не проходите по этим ограничениям? Жуть какая...
 Что именно хотите анализировать потом в Excel? Для подобных объемов я бы сделал так: на SQL накидал бы БД нужной структуры. Грузил бы данные туда. Такие объемы - это уже сфера деятельности систем управления базами данных. Excel не является системой управления БД. Да, Excel умеет кое-что делать с БД, но это для небольших объемов. Для ваших объемов нужно что-то солиднее. | |||
| 38
    
        ssh2006 22.10.18✎ 11:15 | 
        (0) > формирование таблицы значений (обходом табличного документа)
 Для построителя запроса можно в качестве источника данных задать область ячеек табличного документа | |||
| 39
    
        RomanYS 22.10.18✎ 11:15 | 
        (27) 1 млн строк - 25 сек вместе с запросом на ноутбуке:
 Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Банки.Код, | Банки.Наименование |ИЗ | Справочник.Банки КАК Банки"; РезультатЗапроса = Запрос.Выполнить(); Выборка= РезультатЗапроса.Выбрать(); разд = ";"; имяФайла = ПолучитьИмяВременногоФайла(".CSV"); запись = Новый ЗаписьТекста; запись.Открыть(имяФайла, КодировкаТекста.ANSI); Циклов = Цел(1000000/Выборка.Количество()) + 1; ДЛЯ инд = 1 ПО Циклов Цикл Сообщить(""+инд+" из "+Циклов+ " "+ТекущаяДата()); Выборка.Сбросить(); Пока Выборка.Следующий() Цикл стр = Выборка.Код+разд+Выборка.Наименование+разд; запись.ЗаписатьСтроку(стр); КонецЦикла; КонецЦикла; запись.Закрыть(); | |||
| 40
    
        RomanYS 22.10.18✎ 11:16 | 
        +(39) сделай уже замер     | |||
| 41
    
        Fragster гуру 22.10.18✎ 11:18 | 
        (36) а превращать массив в строку ты хочешь через значениевстроку внутр и стрзаменить? это немного быстрее (и то не всегда), но для доработки плохо. Ну и в любой момент может сломаться (с обновлением платформы)     | |||
| 42
    
        Вафель 22.10.18✎ 11:18 | 
        (41) СтрСоединить()     | |||
| 43
    
        Михаил Козлов 22.10.18✎ 11:21 | 
        (37) Есть вариант с БД. Пока речь не о этом.
 (39) Могу предположить, что дело, скорее всего, в занятости дисковой системы. Может и ошибаюсь. (40) Попробую на меньшем объеме. Спасибо всем ответившим. Тему можно считать закрытой. | |||
| 44
    
        Fragster гуру 22.10.18✎ 11:21 | 
        (42) а, ну да. раньше такого не было. тут надо, опять же, измерять.     | |||
| 45
    
        RomanYS 22.10.18✎ 11:22 | 
        +(39) замер:  
 стр = Выборка.Код+разд+Выборка.Наименование+разд; 1 000 186 5,893370 сек 38,32% запись.ЗаписатьСтроку(стр); 1 000 185 3,608695 сек 23,46% Сообщить(""+инд+" из "+Циклов+ " "+ТекущаяДата()); 394 2,565977 сек 16,68% | |||
| 46
    
        assasu 22.10.18✎ 11:22 | 
        (27) под словом "запись" что понимаешь? время записи файла или время работы кода? 
 в (39) показали что это все делается быстро, и отличие от твоего кода только в том что перебирается сразу выборка, а не счетчик строк. | |||
| 47
    
        Fragster гуру 22.10.18✎ 11:26 | 
        (45) а записать(Выборка.Код) + записать(разд) + записать(Выборка.Наименование) + записатьСтроку(разд)?     | |||
| 48
    
        RomanYS 22.10.18✎ 11:34 | 
        (47) тормознее выходит:
 стр = Выборка.Код+разд+Выборка.Наименование+разд; 1 000 185 6,060703 сек 22,90 % запись.записать(Выборка.Наименование); 1 000 185 4,467721 сек 16,88 % запись.записать(Выборка.Код); 1 000 185 3,915113 сек 14,79 % запись.ЗаписатьСтроку(стр); 1 000 185 3,724216 сек 14,07 % запись.записатьСтроку(разд); 1 000 185 2,728079 сек 10,31 % запись.записать(разд); 1 000 185 2,374590 сек 8,97 % | |||
| 49
    
        Fragster гуру 22.10.18✎ 11:36 | 
        а в procmon можешь глянуть, оно на каждый Записать() диск дергает?     | |||
| 50
    
        Fragster гуру 22.10.18✎ 11:37 | 
        ну и да, может проще делать ЗаписьXML.ЗаписатьБезОбработки() в память, а потом одним махом закинуть на диск.     | |||
| 51
    
        Fragster гуру 22.10.18✎ 11:38 | 
        ну или с потоками покрутить что-нибудь (я потоки "от 1с" даже не смотрел ибо сделано через жопу)     | |||
| 52
    
        RomanYS 22.10.18✎ 11:38 | 
        +(48)  
 конкатенация + 1 записатьстроку - 37% 3 записать + 1 записатьстроку - 51% Соотношение, наверное, от диска будет зависеть | |||
| 53
    
        Fragster гуру 22.10.18✎ 11:40 | 
        (52)  у тебя конкатенаций меньше     | |||
| 54
    
        Fragster гуру 22.10.18✎ 11:40 | 
        ну и записать() тоже.     | |||
| 55
    
        RomanYS 22.10.18✎ 11:40 | 
        (49) в (48) 5 млн записей, даже ссд столько не обработает за 15 секунд     | |||
| 56
    
        RomanYS 22.10.18✎ 11:40 | 
        (53) так по идее ещё хуже будет     | |||
| 57
    
        Fragster гуру 22.10.18✎ 11:42 | 
        ну да. и стрингбилдера нормального в 1с нету :(     | |||
| 58
    
        Вафель 22.10.18✎ 11:42 | 
        (57) ну так массив же     | |||
| 59
    
        RomanYS 22.10.18✎ 11:44 | 
        (49) посмотрел монитором пишет в течении всего времени 2-3мБ/сек, а сколько там обращений хз     | |||
| 60
    
        Fragster гуру 22.10.18✎ 11:45 | 
        (58) ну это не то. https://habr.com/post/172689/     | |||
| 61
    
        Вафель 22.10.18✎ 11:46 | 
        (60) именно оно и есть. массив = СтрСоединить().     | |||
| 62
    
        Кирпич 22.10.18✎ 11:50 | 
        (0)нафиг такое делать в 1с вообще? тяп ляп на delphi или C# и готова. час-два работы.     | |||
| 63
    
        Михаил Козлов 22.10.18✎ 11:52 | 
        (62) Как файлы XML читать? Да и "языками я, Петька, не владею".     | |||
| 64
    
        RomanYS 22.10.18✎ 11:53 | 
        (62) распарсить mxl?     | |||
| 65
    
        RomanYS 22.10.18✎ 11:53 | 
        (63) Замер! Замер! Замер!     | |||
| 66
    
        Fragster гуру 22.10.18✎ 11:55 | 
        Записать + ЗаписатьСтроку: 3 990
 ЗаписатьСтроку: 3 561 ЗаписатьСтроку (Инлайн): 3 224 ЗаписатьXML: 5 958 ЗаписатьXML (Инлайн): 4 105 | |||
| 67
    
        Fragster гуру 22.10.18✎ 11:55 | ||||
| 68
    
        Вафель 22.10.18✎ 11:57 | 
        а где через массив?     | |||
| 69
    
        Fragster гуру 22.10.18✎ 11:58 | 
        (68) "Сделай" (с) ВР     | |||
| 70
    
        Fragster гуру 22.10.18✎ 12:00 | 
        СтрСоединить + ЗаписатьСтроку: 7 503
 ЗаписатьСтроку: 3 576 ЗаписатьСтроку (Инлайн): 3 526 | |||
| 71
    
        RomanYS 22.10.18✎ 12:02 | 
        (66) Вывод один ЗаписьТекста - рабочий инструмент, не требующий альтернатив. 
 (70) ТекстовыйДокумент попробуй, наверняка на порядок меделеннее | |||
| 72
    
        Михаил Козлов 22.10.18✎ 12:03 | 
        (65) В следующий раз. Наверное, через месяц.     | |||
| 73
    
        Fragster гуру 22.10.18✎ 12:05 | 
        (71).1 ну да, если в память не надо получить ничего     | |||
| 74
    
        Кирпич 22.10.18✎ 12:06 | 
        (63) "языками я, Петька, не владею"
 дай студенту-программисту на пиво и вопрос решен | |||
| 75
    
        Fragster гуру 22.10.18✎ 12:08 | 
        кстати, никто не сказал, что формирование /csv у автора неправильное и если в строках будет встречаться разделитель или перенос строки - получится очень интересная ошибка     | |||
| 76
    
        Fragster гуру 22.10.18✎ 12:08 | 
        ну и еще есть тектсовый драйвер odbc, который как раз /csv позволяет читать/писать     | |||
| 77
    
        d4rkmesa 22.10.18✎ 12:08 | 
        (62) Обожаю такие комменты. ))     | |||
| 78
    
        RomanYS 22.10.18✎ 12:12 | 
        (72) прогони тысячу строк и ты узнаешь где косяк. Никто тебе не предлагает замер на 12 часов делать.     | |||
| 79
    
        Кирпич 22.10.18✎ 12:12 | 
        (77) скажи еще, что я не прав     | |||
| 80
    
        Tonik992 22.10.18✎ 12:15 | 
        (79) лучше на С     | |||
| 81
    
        H A D G E H O G s 22.10.18✎ 12:18 | 
        Ничего, что автор пишет файл по сети?     | |||
| 82
    
        Кирпич 22.10.18✎ 12:19 | 
        (80) нет лучше на 1с месяц решать проблему. Потом заказчик еще скажет "а чо у меня книга полчаса открывается, мы так не договаривались"     | |||
| 83
    
        RomanYS 22.10.18✎ 12:19 | 
        (74)(79) Если ты не готов решать эту задачу за пиво, то однозначно не прав     | |||
| 84
    
        Fragster гуру 22.10.18✎ 12:21 | 
        (81) ГДЕ?     | |||
| 85
    
        Cool_Profi 22.10.18✎ 12:21 | 
        (81) Откуда инфа?     | |||
| 86
    
        H A D G E H O G s 22.10.18✎ 12:22 | 
        (84) 
 имяФайла = Каталог+имяСети+СТРОКА(часть)+".CSV"; Или тут ИмяСети - это имя сетевого магазина наверное. | |||
| 87
    
        H A D G E H O G s 22.10.18✎ 12:22 | 
        Отбой     | |||
| 88
    
        Кирпич 22.10.18✎ 12:22 | 
        (86) "сеть" - это Магнит или Ашан     | |||
| 89
    
        RomanYS 22.10.18✎ 12:23 | 
        (81) проверил по сети:
 запись.ЗаписатьСтроку(стр); 1 125 576 строк 15,243661 сек | |||
| 90
    
        Сияющий в темноте 22.10.18✎ 12:23 | 
        Сколько платят за решение?
 Продажи,наверное,сначала нужно свернуть,а потом результат в ексель. не верю,что все тае долго считается!!! конечно,если компьютер взяли из музея напрокат,то все может быть. | |||
| 91
    
        Кирпич 22.10.18✎ 12:26 | 
        (83) Я конечно не буду это делать за пиво. Или бесплатно или за деньги :) Задача плёвая, если делать не на 1с.     | |||
| 92
    
        Кирпич 22.10.18✎ 12:32 | 
        Только надо сначала попробовать будут ли в Excel открываться эти файлы. Было дело в 200000 строк файл открывается - хрен дождешься, а потом еще с ним чота делать надо. Может идея грузить в Excel изначально неверная.     | |||
| 93
    
        Tonik992 22.10.18✎ 12:35 | 
        (92) Возможно это так, но имхаю, что раз автор добрался до сюда, то все-таки нужен именно excel. Скорее всего там отдельная учетная система на базе Excel, с макросами.     | |||
| 94
    
        Кирпич 22.10.18✎ 12:47 | 
        (93) ну авторы обычно сообщают, что конкретно было нужно, после 200 поста.     | |||
| 95
    
        Михаил Козлов 22.10.18✎ 13:02 | 
        (94) В (0) вроде бы все сказано: 
 - формат входных файлов MXL; - данные (по дням) свернуть; - выгрузить в Эксель. Т.к. в некоторых случаях в Эксель невозможно, была согласована выгрузка частями в CSV (уже по моей инициативе). (91) Готов дать координаты заказчика. Письмо на мыло (в профиле). Эта задача, насколько я понимаю, частная. Может быть гораздо более объемный проект. | |||
| 96
    
        ам794123 22.10.18✎ 13:03 | 
        (0) Я такую задачку сделал на скд:
 ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(Результат); ПроцессорВывода.Вывести(ПроцессорКомпоновки); Результат.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.TXT); В итоге файл построчно писался 17 часов, с помощью процессора вывода 5 минут | |||
| 97
    
        Михаил Козлов 22.10.18✎ 13:05 | 
        (96) Спасибо, попробую.     | |||
| 98
    
        Кирпич 22.10.18✎ 13:19 | 
        (95) ё маё!!! :) я MXL с XML перепутал :)     | |||
| 99
    
        Кирпич 22.10.18✎ 13:19 | 
        но координаты возьму     | |||
| 100
    
        RomanYS 22.10.18✎ 13:22 | 
        (98) )) (64) видел?     | |||
| 101
    
        RomanYS 22.10.18✎ 13:23 | 
        (97) сделай (78) уже     | |||
| 102
    
        d4rkmesa 22.10.18✎ 13:28 | 
        (98) Не подкачал, бггг. =))     | |||
| 103
    
        d4rkmesa 22.10.18✎ 13:35 | 
        Как то "сводил" сишника и одинэсника, которых хорошо знал по-отдельности, по такой же плевой задаче, на первый взгляд, потом нахватал "минусов" к карме от обоих, и с обоими впоследствии в течение нескольких лет перестал общаться.     | |||
| 104
    
        Кирпич 22.10.18✎ 13:45 | 
        (103) ты слишком серьёзно относишься к жизни. а задача всё равно плёвая.     | |||
| 105
    
        Кирпич 22.10.18✎ 13:46 | 
        +(104) нормальные люди из за такой ерунды не перестают общаться     | |||
| 106
    
        ssh2006 22.10.18✎ 13:58 | 
        (103) кинул с оплатой?     | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |