|
Посоветуйте как можно ускорить обработку больших файлов (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) кинул с оплатой?
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |