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

Посоветуйте как можно ускорить обработку больших файлов (MXL)

Посоветуйте как можно ускорить обработку больших файлов (MXL)
Я
   Михаил Козлов
 
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 Мб.
Возможно, из-за того, что на сервере еще кое-что делалось.
 
 
   Cool_Profi
 
1 - 22.10.18 - 10:33
90 МБ в цсв? Это какого радиуса руки надо иметь?
   Fragster
 
2 - 22.10.18 - 10:37
вот именно "сохранение в CSV через ЗаписьТекста" больше суток? это очень, очень странно. может все-таки будет код?
   RomanYS
 
3 - 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;
    КонецЦикла;
    запись.Закрыть();
КонецПроцедуры
   Fragster
 
5 - 22.10.18 - 10:41
текСтр.ХХХ - это строки?
   assasu
 
6 - 22.10.18 - 10:42
текСтр = данные.Получить(инд-1);

тут трабла. может выполняться очень долго в большой таблице
   Михаил Козлов
 
7 - 22.10.18 - 10:42
(5) Да, это строка таблицы значений.
   Михаил Козлов
 
8 - 22.10.18 - 10:43
(6) А как иначе?
   Cool_Profi
 
9 - 22.10.18 - 10:43
Сын из слов отца, купившего Ладу Калину, знал только слово "колотить"...
   assasu
 
10 - 22.10.18 - 10:44
(8) индексирование нужно по таблице. и поиск по индексу. так быстрее
 
 Рекламное место пустует
   assasu
 
11 - 22.10.18 - 10:45
(10) +  либо алгоритм переделать. не перебирать числа и по числам искать строки , а сразу перебирать строки
   Fragster
 
12 - 22.10.18 - 10:46
(7) я про тип значения колонок
   Fragster
 
13 - 22.10.18 - 10:47
ну и вместо конкатенации через плюс лучше делать ЗаписьТекста.Записать а последним куском ЗаписатьСтроку()
   Михаил Козлов
 
14 - 22.10.18 - 10:48
(10) Не понял, какой поиск по индексу: номер строки - переменная цикла.
(11) Никакие строки не ищу: получаю строку по номеру.
Или я чего-то не понимаю?
(12) Типы значения колонок - строка.
(13) Принято.
   Fragster
 
15 - 22.10.18 - 10:48
и индикатор обновляй раз в 1000 строк, а не каждую строку... сразу не увидел, блин
   VladZ
 
16 - 22.10.18 - 10:49
(0) сохранение в CSV через ЗаписьТекста частями (ограничение Эксель на число строк). - Поставь нормальную версию Эксель. Там нет никаких ограничений. Открывай файл MXL и сохраняй как XLS.
   Fragster
 
17 - 22.10.18 - 10:49
инд=Цел(инд/1000)*1000
 ->
инд % 1000 = 0
   assasu
 
18 - 22.10.18 - 10:50
(14) получение строки по номеру тот же поиск .
   Fragster
 
19 - 22.10.18 - 10:50
(17)+ блин, кто так пишет, да еще и в одну строку. чтобы глаза сломать?
   Fragster
 
20 - 22.10.18 - 10:51
(18) не совсем. но замер производительности ответил бы на многие вопросы.
   aleks_default
 
21 - 22.10.18 - 10:51
(18)Зачем он вообще здесь нужен? Для каждого Текстрока из данные нельзя?
   assasu
 
22 - 22.10.18 - 10:52
(20)да
   Tonik992
 
23 - 22.10.18 - 10:52
(6) Ага.
Попробуйте вместо таблицы значений использовать Массив + Структура (значение каждого элемента).
http://catalog.mista.ru/public/79285/
Здесь сравнение некоторых универсальных коллекций по скорости
   RomanYS
 
24 - 22.10.18 - 10:53
(14) блин, а сделать замер нельзя? Сразу будет видно какая из 3х строк тормозит
   Fragster
 
25 - 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).
К сожалению, не могу запустить в "одиночестве" на сервере.
   Fragster
 
28 - 22.10.18 - 11:01
кстати, можно попробовать вместо ЗаписьТекста ТекствыйДокумент
   RomanYS
 
29 - 22.10.18 - 11:02
(28) не, там точно тормознее
   VladZ
 
30 - 22.10.18 - 11:03
(26) Что значит 2^20?
   Fragster
 
31 - 22.10.18 - 11:03
(29) ну тут хз. может записьтекста в диск срет каждый "записать". Хотя по моим ощущениям самый быстрый - это ЗаписьXML и ЗаписатьБезОбработки
   Fragster
 
32 - 22.10.18 - 11:04
в любом случае без замеров можно долго гадать
   Михаил Козлов
 
33 - 22.10.18 - 11:05
(26) Ограничение на число строк на листе в Эксель.
 
 
   Вафель
 
34 - 22.10.18 - 11:06
может строку сформировать большую через массив, а потом ее разом записать?
   Fragster
 
35 - 22.10.18 - 11:08
(34) создание строк через + тормозит, особенно больших. проведи эксперимент, попробуй сделать строку из миллиона пробелов через "+"
   Вафель
 
36 - 22.10.18 - 11:10
(35) читай внимательно: через массив
   VladZ
 
37 - 22.10.18 - 11:12
(33) И вы не проходите по этим ограничениям? Жуть какая...
Что именно хотите анализировать потом в Excel?

Для подобных объемов я бы сделал так:
на SQL накидал бы БД нужной  структуры. Грузил бы данные туда. Такие объемы - это уже сфера деятельности систем управления базами данных. Excel не является системой управления БД. Да, Excel умеет кое-что делать с БД, но это для небольших объемов.  Для ваших объемов нужно что-то солиднее.
   ssh2006
 
38 - 22.10.18 - 11:15
(0) > формирование таблицы значений (обходом табличного документа)

Для построителя запроса можно в качестве источника данных задать область ячеек табличного документа
   RomanYS
 
39 - 22.10.18 - 11:15
(27) 1 млн строк - 25 сек вместе с запросом на ноутбуке:

    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |    Банки.Код,
    |    Банки.Наименование
    |ИЗ
    |    Справочник.Банки КАК Банки";
    
    РезультатЗапроса = Запрос.Выполнить();
    
    Выборка= РезультатЗапроса.Выбрать();
    
    разд = ";";
    имяФайла = ПолучитьИмяВременногоФайла(".CSV");
    запись = Новый ЗаписьТекста; 
    запись.Открыть(имяФайла, КодировкаТекста.ANSI); 
    Циклов = Цел(1000000/Выборка.Количество()) + 1;
    ДЛЯ инд = 1 ПО Циклов Цикл
        Сообщить(""+инд+" из "+Циклов+ "    "+ТекущаяДата());
        Выборка.Сбросить();
        
        Пока Выборка.Следующий() Цикл
            стр = Выборка.Код+разд+Выборка.Наименование+разд;
            запись.ЗаписатьСтроку(стр);
        КонецЦикла;
    КонецЦикла;
    запись.Закрыть();
   RomanYS
 
40 - 22.10.18 - 11:16
+(39) сделай уже замер
   Fragster
 
41 - 22.10.18 - 11:18
(36) а превращать массив в строку ты хочешь через значениевстроку внутр и стрзаменить? это немного быстрее (и то не всегда), но для доработки плохо. Ну и в любой момент может сломаться (с обновлением платформы)
   Вафель
 
42 - 22.10.18 - 11:18
(41) СтрСоединить()
   Михаил Козлов
 
43 - 22.10.18 - 11:21
(37) Есть вариант с БД. Пока речь не о этом.
(39) Могу предположить, что дело, скорее всего, в занятости дисковой системы. Может и ошибаюсь.
(40) Попробую на меньшем объеме.
Спасибо всем ответившим. Тему можно считать закрытой.
   Fragster
 
44 - 22.10.18 - 11:21
(42) а, ну да. раньше такого не было. тут надо, опять же, измерять.
   RomanYS
 
45 - 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%
   assasu
 
46 - 22.10.18 - 11:22
(27) под словом "запись" что понимаешь? время записи файла или время работы кода?
в (39) показали что это все делается быстро, и отличие от твоего кода только  в том что перебирается сразу выборка, а не счетчик строк.
   Fragster
 
47 - 22.10.18 - 11:26
(45) а записать(Выборка.Код) + записать(разд) + записать(Выборка.Наименование) + записатьСтроку(разд)?
   RomanYS
 
48 - 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    %
   Fragster
 
49 - 22.10.18 - 11:36
а в procmon можешь глянуть, оно на каждый Записать() диск дергает?
 
 Рекламное место пустует
   Fragster
 
50 - 22.10.18 - 11:37
ну и да, может проще делать ЗаписьXML.ЗаписатьБезОбработки() в память, а потом одним махом закинуть на диск.
   Fragster
 
51 - 22.10.18 - 11:38
ну или с потоками покрутить что-нибудь (я потоки "от 1с" даже не смотрел ибо сделано через жопу)
   RomanYS
 
52 - 22.10.18 - 11:38
+(48)  
конкатенация + 1 записатьстроку - 37%
3 записать + 1 записатьстроку - 51%

Соотношение, наверное, от диска будет зависеть
   Fragster
 
53 - 22.10.18 - 11:40
(52)  у тебя конкатенаций меньше
   Fragster
 
54 - 22.10.18 - 11:40
ну и записать() тоже.
   RomanYS
 
55 - 22.10.18 - 11:40
(49) в (48) 5 млн записей, даже ссд столько не обработает за 15 секунд
   RomanYS
 
56 - 22.10.18 - 11:40
(53) так по идее ещё хуже будет
   Fragster
 
57 - 22.10.18 - 11:42
ну да. и стрингбилдера нормального в 1с нету :(
   Вафель
 
58 - 22.10.18 - 11:42
(57) ну так массив же
   RomanYS
 
59 - 22.10.18 - 11:44
(49) посмотрел монитором пишет в течении всего времени 2-3мБ/сек, а сколько там обращений хз
   Fragster
 
60 - 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 читать? Да и "языками я, Петька, не владею".
   RomanYS
 
64 - 22.10.18 - 11:53
(62) распарсить mxl?
   RomanYS
 
65 - 22.10.18 - 11:53
(63) Замер! Замер! Замер!
   Fragster
 
66 - 22.10.18 - 11:55
Записать + ЗаписатьСтроку: 3 990
ЗаписатьСтроку: 3 561
ЗаписатьСтроку (Инлайн): 3 224
ЗаписатьXML: 5 958
ЗаписатьXML (Инлайн): 4 105
   Fragster
 
67 - 22.10.18 - 11:55
   Вафель
 
68 - 22.10.18 - 11:57
а где через массив?
   Fragster
 
69 - 22.10.18 - 11:58
(68) "Сделай" (с) ВР
   Fragster
 
70 - 22.10.18 - 12:00
СтрСоединить + ЗаписатьСтроку: 7 503
ЗаписатьСтроку: 3 576
ЗаписатьСтроку (Инлайн): 3 526
   RomanYS
 
71 - 22.10.18 - 12:02
(66) Вывод один ЗаписьТекста - рабочий инструмент, не требующий альтернатив.
(70) ТекстовыйДокумент попробуй, наверняка на порядок меделеннее
   Михаил Козлов
 
72 - 22.10.18 - 12:03
(65) В следующий раз. Наверное, через месяц.
   Fragster
 
73 - 22.10.18 - 12:05
(71).1 ну да, если в память не надо получить ничего
   Кирпич
 
74 - 22.10.18 - 12:06
(63) "языками я, Петька, не владею"
 дай студенту-программисту на пиво и вопрос решен
   Fragster
 
75 - 22.10.18 - 12:08
кстати, никто не сказал, что формирование /csv у автора неправильное и если в строках будет встречаться разделитель или перенос строки - получится очень интересная ошибка
   Fragster
 
76 - 22.10.18 - 12:08
ну и еще есть тектсовый драйвер odbc, который как раз /csv позволяет читать/писать
   d4rkmesa
 
77 - 22.10.18 - 12:08
(62) Обожаю такие комменты. ))
   RomanYS
 
78 - 22.10.18 - 12:12
(72) прогони тысячу строк и ты узнаешь где косяк. Никто тебе не предлагает замер на 12 часов делать.
   Кирпич
 
79 - 22.10.18 - 12:12
(77) скажи еще, что я не прав
   Tonik992
 
80 - 22.10.18 - 12:15
(79) лучше на С
   H A D G E H O G s
 
81 - 22.10.18 - 12:18
Ничего, что автор пишет файл по сети?
   Кирпич
 
82 - 22.10.18 - 12:19
(80) нет лучше на 1с месяц решать проблему. Потом заказчик еще скажет "а чо у меня книга полчаса открывается, мы так не договаривались"
   RomanYS
 
83 - 22.10.18 - 12:19
(74)(79) Если ты не готов решать эту задачу за пиво, то однозначно не прав
   Fragster
 
84 - 22.10.18 - 12:21
(81) ГДЕ?
   Cool_Profi
 
85 - 22.10.18 - 12:21
(81) Откуда инфа?
   H A D G E H O G s
 
86 - 22.10.18 - 12:22
(84)
 имяФайла = Каталог+имяСети+СТРОКА(часть)+".CSV";

Или тут ИмяСети - это имя сетевого магазина наверное.
   H A D G E H O G s
 
87 - 22.10.18 - 12:22
Отбой
   Кирпич
 
88 - 22.10.18 - 12:22
(86) "сеть" - это Магнит или Ашан
   RomanYS
 
89 - 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 изначально неверная.
   Tonik992
 
93 - 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) Готов дать координаты заказчика. Письмо на мыло (в профиле). Эта задача, насколько я понимаю, частная. Может быть гораздо более объемный проект.
   ам794123
 
96 - 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
но координаты возьму
   RomanYS
 
100 - 22.10.18 - 13:22
(98) )) (64) видел?
  1  2   

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