Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Parallel.ForEach - первый блин комом / 23 сообщений из 23, страница 1 из 1
06.02.2013, 01:09
    #38139203
M234
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel.ForEach - первый блин комом
Возможно я чего-то недопонял или совсем не понял, потому такой наивный вопрос:
Вот эта вот кривая поделка будет копировать файлы с одного источника на Х получателей ПАРАЛЛЕЛЬНО или нет?
Ну то есть например с флэшки сразу на два диска или наоборот с диска на 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
06.02.2013, 01:51
    #38139223
M234
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel.ForEach - первый блин комом
А можно ещё и так изголиться:
Код: c#
1.
2.
3.
4.
5.
6.
7.
Task.Factory.StartNew(() =>
    {
        Parallel.ForEach(DestDirs, dirPath =>
        {          
            CopyAll(sourceDir, dirPath);            
        });
    });



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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

Ну то есть такую CopyAll как я привёл в примере делать не стоит?
Лучше по старинке рекурсивно?
Потестил немного копированием на одном и том же диске из одной папки в другую - так с ForEach сильно быстрее получается.
Здесь что за "частный случай"?
...
Рейтинг: 0 / 0
07.02.2013, 18:07
    #38142292
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel.ForEach - первый блин комом
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
07.02.2013, 18:28
    #38142339
netivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel.ForEach - первый блин комом
МСУ,

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

вот код:
Говнокод[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
07.02.2013, 18:31
    #38142347
Arm79
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel.ForEach - первый блин комом
Чет заглючило

Попытка №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
07.02.2013, 19:04
    #38142410
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel.ForEach - первый блин комом
netivanМСУ,

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

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

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

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

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

да вы не правы, как писать в любом случае решает контроллер диска. И надо сказать крутится он достаточно оперативно.Но мы отвлекаемся от темы.
...
Рейтинг: 0 / 0
08.02.2013, 10:29
    #38142936
netivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel.ForEach - первый блин комом
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
08.02.2013, 10:40
    #38142944
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel.ForEach - первый блин комом
netivan, некорректный замер, котороый основывается на дисковом кеше во втором случае. Создай отдельные фолдеры для последовательного копирования и отдельные для параллельного. И замеряй непересекающиеся файло.
...
Рейтинг: 0 / 0
08.02.2013, 10:41
    #38142946
Arm79
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Parallel.ForEach - первый блин комом
netivan,

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

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

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


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