powered by simpleCommunicator - 2.0.57     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Parallel.ForEach - первый блин комом
23 сообщений из 23, страница 1 из 1
Parallel.ForEach - первый блин комом
    #38139203
M234
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможно я чего-то недопонял или совсем не понял, потому такой наивный вопрос:
Вот эта вот кривая поделка будет копировать файлы с одного источника на Х получателей ПАРАЛЛЕЛЬНО или нет?
Ну то есть например с флэшки сразу на два диска или наоборот с диска на 2е флэшки.
Дополнительный вопрос: Если запустить под Debag'ом, то "Готово!" не появляется.
А вот под Releas'ом MessageBox отрабатывает верно. Почему так?
Спасибо.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
private void button1_Click(object sender, EventArgs e)
        {
            string sourceDir = @"C:\Folder1";
            string[] DestDirs = new string[] { @"C:\Folder2", @"D:\Folder2" };

            //foreach(string destDir in DestDirs) CopyAll(sourceDir,destDir);
            Parallel.ForEach(DestDirs, dirPath =>
            {
                CopyAll(sourceDir, dirPath);                
            });
            MessageBox.Show("Готово!");
        }

        private static void CopyAll(string SourcePath, string DestinationPath)
        {
            string[] directories = System.IO.Directory.GetDirectories(SourcePath, "*.*", SearchOption.AllDirectories);

            Parallel.ForEach(directories, dirPath =>
            {
                Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath));                
            });

            string[] files = System.IO.Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories);

            Parallel.ForEach(files, newPath =>
            {
                File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath), true);                
            });
        }
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38139223
M234
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А можно ещё и так изголиться:
Код: c#
1.
2.
3.
4.
5.
6.
7.
Task.Factory.StartNew(() =>
    {
        Parallel.ForEach(DestDirs, dirPath =>
        {          
            CopyAll(sourceDir, dirPath);            
        });
    });



Скорость копирования какая-то офигительная. 7 ГБ за несколько секунд (меньше полминуты).
Где подвох? ;)
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38139349
SeVa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StartNew не блокирует UI. ForEach не контролирует уровень параллелизма и создает большое кол-во тредов, что дает только тормоза, а не скорость. Вложенные параллельные операторы не нужно делать по этой же причине.
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38139567
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А смысл параллелить копирование файлов, если диск один? И исходний, и целевой. Это только в разы ухудшит быстродействие.
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38139770
M234
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79А смысл параллелить копирование файлов, если диск один? И исходний, и целевой. Это только в разы ухудшит быстродействие.

Нет нет, диск НЕ ОДИН.
Я же написал: Например с винта сразу на ДВЕ флэшки.
Я не знаю как там теоретически, а практический замер показал афигительную скорость по сравнению с обычным синхронным foreach.
У меня вопрос ещё такой: Как сюда влепить простенький Progressbar?
Простенький, потому как не нужен прогресс копирования файлов как таковых, а только прогресс выполнения функций CopyAll,
ну то есть если их в цикле 5 штук то считать только количество выполненых и это отображать в прогрессбаре.
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38139782
M234
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и если "прогрессивный" Parallel для этих целей не подходит, то как сделать иначе?
Открыть "обычным способом" несколько потоков и в них выполнять CopyAll с разными параметрами?
Я вот и спашиваю: А Parallel.ForEach делает не тоже самое?
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38139815
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
M234Я же написал: Например с винта сразу на ДВЕ флэшки.

Читать умеем?

Arm79А смысл параллелить копирование файлов, если диск один? И исходний, и целевой

вот если бы:
диск 1 --> флешка 1
диск 2 --> флешка 2

тогда да, скорость от распараллеливания увеличилась бы.


M234Я не знаю как там теоретически, а практический замер показал афигительную скорость по сравнению с обычным синхронным foreach
Это частный случай. Тут все просто: скорость записи на флешку сильно меньше скорости чтения данных с жеского диска.
Но ведь есть уже usb3.0/eSATA флешки - там такой финт ушами не прокатит
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38139854
M234
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То есть вы хотите сказать, что

Копирование:

Диск1 -> Флэшка1
и после завершения
Диск1 -> Флэшка2

займёт столько же времени как и

Диск1 -> Флэшка1
и "параллельно" (в другом потоке)
Диск1 -> Флэшка2

Я вас правильно понял?

А мне почему-то кажется что если открыть три окошка (диск1, флэшка1, флэшка2) в Windows Explorer (Win 7) и из первого окошка перетащить папку с файлами в два другие, то процесс копирования завершится быстрее чем если поочерёдно.
Это обман зрения такой?
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38139935
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
M234Это обман зрения такой?
Это попытка поспорить со мной не пытаясь вчитаться в мои ответы и понять суть.

Диск у вас один. Последовательное чтение с него ну скажем происходит со скоростью 70 МБ/сек. Непоследовательно чтение приводит к тому, что головка диска вынуждена постоянно перемещаться по диску для чтения данных разных файлов (или тех же самых, но больших). Именно для того, чтобы обеспечить как можно большую часть последовательного чтения файлов, используется дефрагментация диска. Так вот, непоследовательное чтение уменьшает скорость в разы.

Теперь с флешкой. Если скорость записи на флешку составляет ну скажем 5-10 МБ/сек, это значит, что при последовательном чтении вы можете параллельно писать не более 6-7 флешек за раз. Непоследовательное чтение ИМХО ограничит вас максимум 4 флешками зараз.

Как только скорость записи на флешку увеличиться, естественно, количество одновременно используемых флешок уменьшится

Теперь, если вы пишете утилиту копирования с одного источника на другой, то для обеспечения максимальной скорости вы должны проанализировать скорости выдачи с источника и скорость записи на целевую систему. И параллелить процессы. ИМХО достаточно нетривиальная задача, учитывая, что что эти скорости нелинейны.

Вам не кажется, что проще и надежнее не заморачиваться и исходить из принципа - количество потоков = MIN(количество источников, количество приемников)?
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142215
M234
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeVaStartNew не блокирует UI. ForEach не контролирует уровень параллелизма и создает большое кол-во тредов, что дает только тормоза, а не скорость. Вложенные параллельные операторы не нужно делать по этой же причине.

Ну то есть такую CopyAll как я привёл в примере делать не стоит?
Лучше по старинке рекурсивно?
Потестил немного копированием на одном и том же диске из одной папки в другую - так с ForEach сильно быстрее получается.
Здесь что за "частный случай"?
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142292
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeVaForEach не контролирует уровень параллелизма и создает большое кол-во тредов
Глупости. Много тредов тебе никто и не даст, опять забыл про пул потоков.

Вот тут на 1 млн. элементов пул отдал мне только 9 потоков.

Код: c#
1.
2.
3.
4.
var ids = new ConcurrentBag<int>();
Parallel.ForEach(ParallelEnumerable.Range(1, 1000000), (i) => { if (!ids.Contains(Thread.CurrentThread.ManagedThreadId)) ids.Add(Thread.CurrentThread.ManagedThreadId); });
Console.WriteLine(ids.Count);
Console.Read();
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142339
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУ,

а ты хотел 1 млн потоков? =)
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142343
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Без понятия, что у вас

вот код:
Говнокод[SRC C#] class Program
{
static void Main(string[] args)
{
var stopwatch = new Stopwatch();

stopwatch.Start();
File.Copy(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329.iso", @"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso");
File.Copy(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848.iso", @"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso");
stopwatch.Stop();
Console.WriteLine("Elapsed sequential sek {0}", stopwatch.ElapsedMilliseconds / 1000);
stopwatch.Reset();
File.Delete(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso");
File.Delete(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso");

stopwatch.Start();
var task1 = Task.Factory.StartNew(() => File.Copy(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329.iso", @"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso"));
var task2 = Task.Factory.StartNew(() => File.Copy(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848.iso", @"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso"));
task1.Wait();
task2.Wait();
stopwatch.Stop();
Console.WriteLine("Elapsed async sek {0}", stopwatch.ElapsedMilliseconds / 1000);
stopwatch.Reset();
File.Delete(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso");
File.Delete(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso");

stopwatch.Start();
var lst = new List<string>(new[] {@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329.iso", @"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848.iso"});
Parallel.ForEach(lst, file => File.Copy(file, file + "_2"));
stopwatch.Stop();
Console.WriteLine("Elapsed parallel sek {0}", stopwatch.ElapsedMilliseconds / 1000);
stopwatch.Reset();
lst.ForEach(file => File.Delete(file + "_2"));

Console.ReadLine();
}
}[src]

результаты: 79, 87, 86 сек. Есть разница?

За такую небольшую разницу скажем спасибо моиму диску и его кэшу.

ЗЫ Особенно наглядно это будет выглядеть, если читать с одного CD/DVD и писать куда-нибудь еще
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142347
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чет заглючило

Попытка №2
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
    class Program
    {
        static void Main(string[] args)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            File.Copy(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329.iso", @"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso");
            File.Copy(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848.iso", @"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso");
            stopwatch.Stop();
            Console.WriteLine("Elapsed sequential sek {0}", stopwatch.ElapsedMilliseconds / 1000);
            stopwatch.Reset();
            File.Delete(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso");
            File.Delete(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso");

            stopwatch.Start();
            var task1 = Task.Factory.StartNew(() => File.Copy(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329.iso", @"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso"));
            var task2 = Task.Factory.StartNew(() => File.Copy(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848.iso", @"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso"));
            task1.Wait();
            task2.Wait();
            stopwatch.Stop();
            Console.WriteLine("Elapsed async sek {0}", stopwatch.ElapsedMilliseconds / 1000);
            stopwatch.Reset();
            File.Delete(@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329-2.iso");
            File.Delete(@"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848-2.iso");

            stopwatch.Start();
            var lst = new List<string>(new[] {@"D:\Test\SW_DVD5_NTRL_Visual_Studio_2010SP1_MultiLang_FPP_VL_MLF_X17-40329.iso", @"D:\Test\SW_DVD5_VS_Ultimate_2012_Russian_Core_MLF_X18-35848.iso"});
            Parallel.ForEach(lst, file => File.Copy(file, file + "_2"));
            stopwatch.Stop();
            Console.WriteLine("Elapsed parallel sek {0}", stopwatch.ElapsedMilliseconds / 1000);
            stopwatch.Reset();
            lst.ForEach(file => File.Delete(file + "_2"));

            Console.ReadLine();
        }
    }



ЗЫ Оба файла примерно по полтора гига каждый
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142410
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanМСУ,

а ты хотел 1 млн потоков? =)

А большое количество это сколько? )
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142828
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79,

например на SSD разница будет. Да и на обычном ХДД тоже,но не в Х раз конечно. БД как-то же работают на дисках)
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142886
Фотография Ken@t
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanArm79,

например на SSD разница будет. Да и на обычном ХДД тоже,но не в Х раз конечно. БД как-то же работают на дисках)
Угу хоть усрись, но последовательный доступ на шпиндель, а с ссд ещё хуже на записи.

БД секционируют , журналы и tempdb на разные шпиндели, для параллелизма записи - чтения.
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142897
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ken@t,

да вы не правы, как писать в любом случае решает контроллер диска. И надо сказать крутится он достаточно оперативно.Но мы отвлекаемся от темы.
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142936
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivan,

не выдержал сделал пример. Обычный диск какой то Сигейт 7200 оборотов. Копирую файл с диска на диск в разные папки.
Последовательно 2 секунды, параллельно 1.2 в среднем. Так что разница есть.
говнокод:

static void CopyTest()
{
var stopwatch = new Stopwatch();
var dirs = new List<string>() {@"c:\copytemp1",@"c:\copytemp2" };
string filename = @"flashtool.7z";
dirs.ForEach(a =>
{
if (!Directory.Exists(a))
{
Directory.CreateDirectory(a);
}
});
//последовательно
stopwatch.Start();
//Parallel.ForEach(dirs, d => File.Copy(Path.Combine(@"c:\", filename), Path.Combine(d, filename)));
File.Copy(Path.Combine(@"c:\",filename),Path.Combine(dirs[0],filename));
File.Copy(Path.Combine(@"c:\", filename), Path.Combine(dirs[1], filename));
stopwatch.Stop();
dirs.ForEach(a =>
{
if (Directory.Exists(a))
{
Directory.Delete(a, true);
}
});
Console.WriteLine(stopwatch.Elapsed);
Console.Read();
//удаляем




}
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142944
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivan, некорректный замер, котороый основывается на дисковом кеше во втором случае. Создай отдельные фолдеры для последовательного копирования и отдельные для параллельного. И замеряй непересекающиеся файло.
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142946
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivan,

какого размера файлы? если не очень большие, то они вполне могут быть в кэше диска. Я же специально для теста выбрал большие файлы, а мой тест - аналог вашего
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38142951
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79,

179 мб, не сказал бы что маленький. Попробую найти больше)
...
Рейтинг: 0 / 0
Parallel.ForEach - первый блин комом
    #38144092
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
netivanArm79,

179 мб, не сказал бы что маленький. Попробую найти больше)
ico какой-нибудь
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Parallel.ForEach - первый блин комом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]