Pertanyaan Apakah PLinq Lebih Cerah daripada System.Threading.Tasks.Parallel.ForEach


Ringkasan: Saya mengubah dari System.Threading.Tasks.Parallel.ForEach dan Concurrent Data struktur ke plinq sederhana (Parallel Linq) query. Kecepatannya meningkat luar biasa.

Jadi apakah plinq secara inheren lebih cepat dari Parallel.ForEach? Atau itu khusus untuk tugas itu.

// Original Code
// concurrent dictionary to store results
var resultDict = new ConcurrentDictionary<string, MyResultType>();

Parallel.ForEach(items, item =>
        {
            resultDict.TryAdd(item.Name, PerformWork(source));
        });


// new code

var results =
            items
            .AsParallel()
            .Select(item => new { item.Name, queryResult = PerformWork(item) })
            .ToDictionary(kv => kv.SourceName, kv => kv.queryResult);

Catatan: Setiap tugas (PerformWork) sekarang berjalan antara 0 dan 200 ms. Dulu butuh waktu lebih lama sebelum saya mengoptimalkannya. Itu sebabnya saya menggunakan perpustakaan Tasks.Parallel di tempat tinju. Jadi saya pergi dari 2 detik total waktu ke ~ 100-200 ms total waktu, melakukan pekerjaan yang kira-kira sama, hanya dengan metode yang berbeda. (Wow linq dan plinq luar biasa!)

Pertanyaan:

  1. Apakah mempercepat karena menggunakan plinq vs Parallel.ForEach?
  2. Apakah ini bukan hanya penghapusan struktur data bersamaan (ConcurrentDictionary)? (Karena tidak perlu menyinkronkan utas).
  3. Berdasarkan jawaban dari ini pertanyaan terkait

Sedangkan PLINQ sebagian besar didasarkan pada gaya pemrograman fungsional tanpa efek samping, efek samping adalah tepat untuk apa TPL. Jika Anda ingin benar-benar bekerja secara paralel daripada hanya mencari / memilih hal-hal secara paralel, Anda menggunakan TPL.

Dapatkah saya berasumsi bahwa karena pola saya pada dasarnya berfungsi (memberi masukan menghasilkan keluaran baru tanpa mutasi), bahwa teknologi yang benar adalah teknologi yang benar?

Saya mencari validasi bahwa asumsi saya benar, atau indikasi bahwa saya kehilangan sesuatu.


7
2018-03-04 16:09


asal


Jawaban:


Berdasarkan informasi terbatas yang Anda berikan dalam sampel Anda (saya meminta detail lebih lanjut dalam komentar di OP), saya menduga Anda melihat perbedaan karena algoritma partisi yang digunakan. Anda harus membaca terus Chunk Partitioning vs. Range Partitioning dalam posting blog ini di mana dia membahas bagaimana mereka berbeda dan jenis pekerjaan apa yang paling cocok untuk mereka. Sangat menyarankan Anda membaca artikel blog itu juga yang ini yang masuk ke sedikit lebih detail pada kedua jenis tersebut bersama dengan dua jenis partisi lain yang dapat digunakan, meskipun tidak berlaku untuk sampel Anda, serta memberikan beberapa alat bantu visual untuk lebih memahami partisi. Akhirnya, inilah pos blog lain yang membahas pembagian kerja dan bagaimana itu dapat mempengaruhi Anda ketika algoritma partisi default tidak masuk akal untuk beban kerja khusus Anda. Posting itu sebenarnya mengacu pada program hebat yang membantu Anda memvisualisasikan partisi di tempat kerja itu bagian dari satu set sampel paralel dari tim PFX.


2
2018-03-04 22:21



Tidak mungkin menggunakan 2 contoh kode ini untuk melakukan perbandingan definitif Parallel.ForEach dan PLINQ. Sampel kode terlalu berbeda.

Item pertama yang melompat ke arah saya adalah contoh pertama yang digunakan ConcurrentDictionary dan kegunaan kedua Dictionary. Kedua jenis ini memiliki kegunaan dan karakteristik kinerja yang sangat berbeda. Untuk mendapatkan perbandingan akurat antara dua teknologi yang Anda perlu konsisten di sini dengan jenisnya.


4
2018-03-04 16:12