| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: WinAPI и системное программирование > Быстрое копирование большого количества файлов |
| Автор: XperT 1.5.2012, 11:51 |
| Бьюсь сейчас над решением задачи быстрого копирования большого количества файлов. Ситуация такова, что при использовании функции CopyFileEx на файлах в количестве 30 000 программе необходимо около 6 мин, в то время, как копирование этих же файлов с помощью проводника отнимает чуть больше полторы минуты. Подозреваю, что всё дело в том, что ОС это делает в несколько потоков, потому вижу 2 варианта решения проблемы: 1. Самому делать в это в несколько потоков (не факт, что сработает, так как возможно, что все запросы на копирование файлов с помощью функции CopyFileEx становятся в очередь) 2. Найти функцию, которая отправляет на копирование не один файл, а группу файлов, чтобы ОС сама могла распределять свои ресурсы для самого оптимального копирования Более предпочтительным есть второй вариант, но не уверен, что в WinAPI найдется подобная функция. Если кто-то знает о её существовании или имеет еще какие-то варианты решения проблемы - буду очень признателен. |
| Автор: kami 1.5.2012, 14:10 |
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762164(v=vs.85).aspx |
| Автор: XperT 1.5.2012, 17:31 | ||
К сожалению скорость от использования этой функции не выросла: во-первых очень медленно проходит подготовка файлов (секунд 30-40), по всей видимости в это время парсится входящая строка, а во вторых скорость копирования такая же как при использовании CopyFileEx (в окне копирования пишет 1,26 МБ/сек, при том, что во время копирования через проводник скорость 5 МБ/сек). Может кто-то знает другие способы быстрого копирования файлов? |
| Автор: Keeper89 1.5.2012, 20:51 | ||
А можно попробовать наоборот, сначала проводник, а потом программа. |
| Автор: XperT 1.5.2012, 21:06 |
| Попробовал наоборот, ничего не поменялось, проводник копирует минимум в 5 раз быстрее |
| Автор: Keeper89 1.5.2012, 22:42 |
| XperT, покажи код. |
| Автор: XperT 1.5.2012, 22:58 | ||||
Класс делал с заделом на будущее:
Проверял на таком коде:
|
| Автор: northener 2.5.2012, 00:27 |
| Смущает меня то, что сравнивается не время копирования а "значение скорости копирования" выдаваемое окном визуализации процесса копирования. И ещё одно смущает. В методе TFileProccessing.CopyFiles структура SHFileOpStruct - локальная переменная, но никакого предварительного обнуления сей структуры не производится. Следовательно некоторые поля этой структуры явно задаются в коде метода, а прочие остаются на усмотрение Александра Сергеевича. |
| Автор: XperT 2.5.2012, 10:45 | ||||
Проводник копирует за 1-1,5 мин, программа за 6-7 мин. Точных вычислений не делал, и так прекрасно видно, что разница в скорости очень большая. В посте приводил данные по скорости копирования из окна копирования потому, что соотношения соотвествуют временным.
Какие прочие? Все свойства структуры заполнены, проверял через дебагер. |
| Автор: XperT 2.5.2012, 14:29 |
| После перезагрузки провел еще один эксперимент: сначала копировал проводником, потом через программу. Проводник: Процесс копирования запустился сразу, без задержек на оценку. Продолжительность копирования: 2 мин 50 сек Программа: 1. Сначала запустилась оценка: ![]() Это продолжалось 48 сек. 2. Потом запустилось само копирование. Продолжительность ~ 2 мин 3. Под конец копирования окошко подвисло в таком состоянии: ![]() Длилось это 3 мин 39 сек Итого: 6 мин 27 сек против 2 мин 50 сек |
| Автор: northener 2.5.2012, 17:07 | ||
Чем они заполнены, если вы сами их не заполняли? Мусором? |
| Автор: XperT 2.5.2012, 17:30 | ||||
Кто они? Вы видели описание структуры? Покажите мне хоть одно свойство которое я не заполняю? |
| Автор: northener 2.5.2012, 23:42 |
Да. Был не прав, признаю. Значит надо попробовать разобраться из-за чего происходит это подвисание. Ибо весь остальной процесс выполняется за такое же время как и процесс копирования в проводнике. |
| Автор: XperT 3.5.2012, 00:11 | ||
Не совсем весь, первый пункт так же не наблюдается в проводнике. Вроде и мигает в нём что-то вроде оценки, но буквально на пол секунды, а тут почти минута. Я предполагаю, что идёт парсинг передаваемой строки, вопрос только почему так медленно. Да и в ряд ли тут что-то поделаешь, не так много в этой функции свойств и флагов, чтобы можно было экспериментировать и искать оптимальные варианты, а больше по сути ничего и не сделаешь. В любом случае проблему решил другим путем: копирование файлов через CopyFileEx в несколько потоков. Опытным путем было вычислено, что при разбиении списка файлов на 3 равных части и копирования каждой в отдельном потоке даёт самую оптимальную скорость. На тех же файлах скорости копирования находится в диапазоне 120-150 сек. Увеличивание количества потоков даёт очень маленький прирост (скорее всего всё дело упирается в скорость работы винта, что собственно и требовалось сделать). Тему можно считать закрытой. |
| Автор: northener 3.5.2012, 00:32 |
Для вас да. А вот меня она заинтересовала. Ибо скорость копирования - это скорость копирования не более того. Тем более, что скорость копирования зависит ещё и от конфигурации компьютерного железа. А вот время выполнения копирования функцией SHFileOperation мне гораздо более интересно. Как, когда и от чего это время зависит? |
| Автор: XperT 3.5.2012, 00:35 | ||
Ну если разберетесь - буду рад услышать решение. К сожалению у меня проект стоял пока я этим копированием занимался и пришлось удовлетворятся тем, что имел (тем более, что производительность та же, да и с отловом ошибок при копировании большого количества файлов проще). |
| Автор: northener 3.5.2012, 00:49 |
Ну тогда помогите мне задать начальные условия для проверки. Как вы формировали список из 30000 файлов для копирования? 1. В случае копирования через проводник 2. В случае копирования через вашу программу |
| Автор: XperT 3.5.2012, 12:10 |
| Есть папка с файлами (пробовал по разному: и с подпапками, и все картинки в одной папке - разницу не заметил). В папке находятся аватарки в большом количестве (по сути большое количество маленьких файлов) 1. В проводнике: выделяю папку -> Ctrl+C -> открываю другую папку (на другом диске) -> Ctrl+V 2. В программе: парсится папка с файлами -> формируется список файлов -> отправляется в функцию копирования файлов Замер скорости копирования во втором случае начинается с момента появления окошка копирования (т.е. исключается время парсинга списка файлов). |
| Автор: Keeper89 3.5.2012, 18:19 |
| Ну ты в одном случае копируешь папку, а в другом список файлов. Что если попробовать делать копии одного и того же, например папку в обоих случаях? |
| Автор: XperT 3.5.2012, 22:02 |
| Дело в том, что в некоторых случаях программа должна копировать не все файлы, а в некоторых даже не все файлы в одну папку, потому интересовал универальный способ быстрого копирования |
| Автор: northener 3.5.2012, 23:42 | ||
Вот почему я и спросил "Как вы формировали список из 30000 файлов для копирования?". Продолжаю настаивать на том, что нужно разобраться в причинах того самого зависания. |
| Автор: Keeper89 4.5.2012, 00:04 | ||
Все-таки сравнивать нужно одни и те же вещи - проводник копирует папку, и в программе копируем папку. Также и с файлами - если формируем список сами, также сделать и в проводнике если получится. Уверен, что результаты будут при прочих равных условях одинаковыми. |
| Автор: XperT 4.5.2012, 13:30 |
| Проводник: 1. Зашел в папку с картинками, выделил все файлы, копировал - произошла задержка на 5 сек 2. Открыл папку назначения, Ctrl + V, произошла задержка в 3 сек для оценки и сразу запустилось копирование 3. Процесс копирования длился 3 мин 15 сек 4. Под конец копирования никаких зависаний не было, окно сразу же закрылось Итого: немного медленее чем при копировании папки, но всё равно на много быстрее чем через SHFileOperation |
| Автор: Keeper89 4.5.2012, 15:23 |
| Мне прям интересно стало, надо вечером вбить, попробовать |
| Автор: XperT 4.5.2012, 17:32 |
| Есть подозрение, что в Вин7 проводник использует другую WinAPI функцию для копирования (которая появилась только в висте или 7). |