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

  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   

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует