Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Производительность алгоритма.
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Пользователю 1С 7.7 > Платформа 7.7
l2d808
Доброго времени суток. Платформа7.7

Задача: Есть 2 эксель файла по 5000 позиций в каждом (приблизительно). нужно зделать выборку по условии в третий файл. Вопрос: Эфективность(скорость) роботы обработки будет выше если сначала переместить эти файлы в ТЗ, а уж потом обрабатывать или напрямую робота с ексель файлами, или нет никакой разницы в скорости в обоих случаях?
Если кто эксперементировал, подскажите. Мне лень писать 2 обработки и сравнивать их потом. ))) Проще написать одну. :-)
Спасибо за понимание.
Vofka
Я думаю, на 5000 строк вы особой разницы не почувствуете smile.gif . Та и писать то тут, в принципе, фигня. Процентов 70 кода будет одинакового в обоих обработках wink.gif
l2d808
Цитата(Vofka @ 26.07.12, 9:03) необходимо зарегистрироваться для просмотра ссылки
Я думаю, на 5000 строк вы особой разницы не почувствуете smile.gif . Та и писать то тут, в принципе, фигня. Процентов 70 кода будет одинакового в обоих обработках wink.gif

:-) Уже почти дописал... Протестирую и напишу разницу во времени... А так же код... Может кому пригодится.. ))))

Для теста я использовал:
1. Виртуальный диск выделенный в оперативной памяти.
2. Два ексель документа по 5000 позиций
3. Алгоритм прямой роботы с ексель. (А)
4. Алгоритм роботы через Таблицу Значений. (Б)
Результат:
Алгоритм А показал 5 минут и 19 секунд
Алгоритм Б показал 52 секунды.

Привожу Вашему вниманию более быстрый biggrin.gif
Извините за то-что он не изящен. biggrin.gif
Торпился написать и протестить. 31000000.gif

Процедура Выполнить2()
Имя=КаталогИБ()+"\xls\open.xls";
Лист=СоздатьОбъект("Excel.Application");
Лист.Workbooks.Open(Имя); //Добавляем новый документ
ТЗ1 = СоздатьОбъект("ТаблицаЗначений");
ТЗ1.НоваяКолонка("Код");  
ТЗ1.НоваяКолонка("Имя");
ТЗ1.НоваяКолонка("Цена");
Лист.ScreenUpdating = 0;  
Лист.EnableEvents = 0;    
Лист.Visible = 0;        
сч=0;
строкаЕхель=1;
пока сч<10 Цикл
    Ячейка=СокрЛП(Лист.Cells(строкаЕхель,2).Value);     
    Если Ячейка="" Тогда
        сч=сч+1;
    Иначе
        сч=0;
        ТЗ1.НоваяСтрока();
        ТЗ1.Код=СокрЛП(Лист.Cells(строкаЕхель,1).Value);
        ТЗ1.Имя=СокрЛП(Лист.Cells(строкаЕхель,2).Value);
        ТЗ1.Цена=0;
        //Сообщить(ТЗ1.Код);
        //Сообщить(ТЗ1.Имя);
    КонецЕсли;
    строкаЕхель=строкаЕхель+1;
КонецЦикла;      


Имя2=КаталогИБ()+"\xls\test.xls";
Лист2=СоздатьОбъект("Excel.Application");
Лист2.Workbooks.Open(Имя2); //Добавляем новый документ
ТЗ2 = СоздатьОбъект("ТаблицаЗначений");
ТЗ2.НоваяКолонка("Имя");  
ТЗ2.НоваяКолонка("Цена");
сч=0;
строкаЕхель=1;
пока сч<10 Цикл
    Ячейка=СокрЛП(Лист2.Cells(строкаЕхель,1).Value);     
    Если Ячейка="" Тогда
        сч=сч+1;
    Иначе
        сч=0;            
        ТЗ2.НоваяСтрока();
        ТЗ2.Имя=СокрЛП(Лист.Cells(строкаЕхель,1).Value);
        ТЗ2.Цена=СокрЛП(Лист.Cells(строкаЕхель,6).Value);
        //Сообщить(ТЗ2.Имя);
        //Сообщить(ТЗ2.Цена);
    КонецЕсли;
    строкаЕхель=строкаЕхель+1;
КонецЦикла;

Имя3=КаталогИБ()+"\xls\Результат.xls";
Лист3=СоздатьОбъект("Excel.Application");
Лист3.Workbooks.Open(Имя3); //Добавляем новый документ
строкаЕхель=1;
ТЗ1.ВыбратьСтроки();
Пока ТЗ1.ПолучитьСтроку()=1 Цикл
    ТЗ2.ВыбратьСтроки();
    Пока ТЗ2.ПолучитьСтроку()=1 Цикл
        Если ТЗ1.Имя=ТЗ2.Имя Тогда  
            Лист3.Cells(строкаЕхель,1).Value=ТЗ1.Код;
            Лист3.Cells(строкаЕхель,2).Value=ТЗ1.Имя;
            Лист3.Cells(строкаЕхель,3).Value=ТЗ1.Цена;
            //Сообщить();
            //Сообщить(ТЗ1.Код);
            //Сообщить(ТЗ1.Имя);
            //Сообщить(ТЗ2.Цена);
            строкаЕхель=строкаЕхель+1;
        КонецЕсли;
    КонецЦикла;
КонецЦикла;  
//******************************************************
Лист.ScreenUpdating = 1;  //Ускореем
Лист.EnableEvents = 1;    //Вывыд
Лист.Visible = 1;         //в EXEL
//******************************************************    
Сообщить(ТекущееВремя());
форма.закрыть();
КонецПроцедуры
Vofka
Медленный вариант для сравнения тоже было бы интересно посмотреть smile.gif

Цитата
нужно зделать выборку по условии в третий файл.

Я просто подумал, что нужно из одного файла и второго по условию для каждого отдельно что-то выбрать в третий файл. Но по коду выше, видимо, нужно сравнивать между собой записи в эксэль файлах 1 и 2 (каждую строку с каждой) и результаты писать в третий. В общем, я в таком случае не удивлен результатом smile.gif .
logist
Медленный вариант будет работать быстрее (не 52 секунды, но и не 5 минут) если читать файл порциями.
l2d808
Цитата(logist @ 26.07.12, 10:19) необходимо зарегистрироваться для просмотра ссылки
если читать файл порциями.

Простите пожалуйста. Я наверное не знаю как єто зделать... Если Вам не трудно, покажите код.
logist
Цитата(l2d808 @ 26.07.12, 10:24) необходимо зарегистрироваться для просмотра ссылки
Если Вам не трудно, покажите код.

Я давал совет из практики по упр.прил. 8.2., вкратце это выглядит так (это код 8.2. УП):

Функция ПолучитьПорциюСтрокИзExcelФайла(НачСтрока, КонСтрока, ПутьФайла)
    
    xlLastCell = 11;
    НомерЛистаExcel = 1;
    ИмяФайла = СокрЛП(ПутьФайла);
    ВыбФайл = Новый Файл(ИмяФайла);
    Если НЕ ВыбФайл.Существует() Тогда
        Сообщить("Файл не существует!");
        Возврат Ложь;
    КонецЕсли;
    
    Попытка    
        Excel = Новый COMОбъект("Excel.Application");
        Excel.WorkBooks.Open(ИмяФайла);        
        ExcelЛист = Excel.Sheets(НомерЛистаExcel);
    Исключение
        Сообщить(ОписаниеОшибки());
        Возврат ложь;
    КонецПопытки;
    
    ActiveCell = Excel.ActiveCell.SpecialCells(xlLastCell);
    RowCount = ActiveCell.Row;
    ColumnCount = ActiveCell.Column;
    
    Для Row = НачСтрока По КонСтрока Цикл
// здесь читаем строки и пишем их в таблицу
Значение = ExcelЛист.Cells(Row,НомерКолонки).Value;
    КонецЦикла;
    Excel.WorkBooks.Close();
    Excel = 0;
    
    Возврат ТаблицаЗагрузки;
    
КонецФункции
l2d808
Платформы немного отличаются. Но общий фон я понял. Я так и сделал в варианте Б. ексель лист передал в ТЗ и обрабатывал я уже Таблицу значений. Я думал существует алгоритм который ускорит роботу при прямой роботе с диском: типа честями брать файлы и эти части как-то обрабатывать в процессе.
logist
Цитата(l2d808 @ 26.07.12, 10:52) необходимо зарегистрироваться для просмотра ссылки
Я так и сделал в варианте Б. ексель лист передал в ТЗ и обрабатывал я уже Таблицу значений.

Вы не поняли совсем то что выше - это процедура которая читает порцию и передает ее в ТЗ, именно ПОРЦИЮ а не сразу весь файл, в этом и есть выигрыш производительности.
sava1
Цитата(logist @ 26.07.12, 11:48) необходимо зарегистрироваться для просмотра ссылки
есть выигрыш производительности.

т.е. 5000 раз создать КОМ-объект и открыть файл даст прирост в производительности ???
Если проблема в чтении - используйте АДО - быстрее не получится
l2d808
Цитата(logist @ 26.07.12, 11:48) необходимо зарегистрироваться для просмотра ссылки
это процедура которая читает порцию и передает ее в ТЗ,

Я действительно не понял... как при помощи алгоритма, в данной ситуации, реально улучшить скорость обмена между шиной и HDD, на порядок выше или равно со скоростью обмена между шиной и ОЗУ? у меня ОЗУ DDR3-2400 скорость которой - 19200МБ/с. А HDD hitachi Внутренняя скорость передачи данных 170 Мбайт/с. и того 19200/170=112,941 раз приблизительно. Возможно данный алгоритм и улучшит производительность системы, при условии, если брать информацию не блокими, а целым файлом... Но Вы меня не убедили... Ваш алгоритм не работает по принципах, которые Вы регламентировали выше. Или возможно я не д конца все понял... Если Вам не будет трудно, адаптируйте Ваш принцип порционной обработки под версию 7,7.
Век живи, век учись... Хочу научится... И сообщесттву будет интересно...
Мне нравятся нестандартные решения, хотя, они не всегда оптимальны...
Простите меня за каламбуры, но этот алгоритм я хотел бы понять....
А так же спасибо и Вам за понимание...

Цитата(sava1 @ 26.07.12, 13:48) необходимо зарегистрироваться для просмотра ссылки
используйте АДО

Вы смотрите на проблему с позиции сольного програмиста. Достаточно проблематично научить пользователей понять что АДО это тоже среда))))
sava1
Цитата(l2d808 @ 27.07.12, 0:31) необходимо зарегистрироваться для просмотра ссылки
научить пользователей понять что АДО это тоже среда


А при чем тут пользователи?
Вы написали обработку, использующую стандартный функционал Винды, а пользователю вооще
по-барабану - как вы получаете данные из екселя (да и до оптимальности алгоритма)
l2d808
Если ваша программа работает медленно, значит, вы опередили время.
logist
Цитата(l2d808 @ 27.07.12, 0:31) необходимо зарегистрироваться для просмотра ссылки
Если Вам не будет трудно, адаптируйте Ваш принцип порционной обработки под версию 7,7.

Будет трудно, я не знаю 7.7.
Оценку производительности я оценил сугубо по визуальному времени выполнения, есть DBF файл 49881 строка, если читать сразу файл в таблицу (при этом происходят еще некоторые действия с данными) то выполняется ~31-33 минут, если читать порциями по 200 строк то выполняется ~23-25 минут. В чем выигрыш не знаю, я не настолько специалист, что бы рассуждать о производительности на уровне шины и ОЗУ. Я вижу что процесс выполняется быстрее, мне этого достаточно.
l2d808
Цитата(logist @ 27.07.12, 9:38) необходимо зарегистрироваться для просмотра ссылки
выполняется ~31-33 минут, если читать порциями по 200 строк то выполняется ~23-25 минут. В чем выигрыш не знаю

Возможно у Вас специфика обработки передаваемых данных в програму такова, что порционноость у Вас играет роль. В моем случае нужно в полном обьеме сопоставлять данные из двух источников. Вот поэтому я и удивился - узнав что может быть алгоритм сопоставления двух массивов на основе порционного забора данных. Такой алгоритм розработать можно (как мне кажется), но прироста производительности в этом случае мы не добьемся. При увеличении цикличности в алгоритмах - увеличевается машинное время на реализацию оных.
pablo
А это уже из области теории алгоритмов smile.gif Порционность в сопоставлении данных возможна, если данные предварительно отсортировать по признаку сравнения wink.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.