Имя: Пароль:
1C
 
Посоветуйте как можно ускорить обработку больших файлов (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 Мб.
Возможно, из-за того, что на сервере еще кое-что делалось.
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) кинул с оплатой?
Закон Брукера: Даже маленькая практика стоит большой теории.