2011-12-16 31 views
5

Sự khác biệt giữa hai loại này là gì?Sự khác biệt linq và plinq

Cách tốt nhất để so sánh là gì?

Nó luôn luôn là tốt hơn plinq?

Khi chúng tôi sử dụng plinq?

+0

một số thông tin tốt tại đây http://www.scip.be/index.php ? Page = ArticlesNET08 & Lang = EN – user1231231412

+0

Tôi nghĩ rằng nó khá an toàn để giả định rằng nếu nó luôn luôn tốt hơn để sử dụng PLINQ, LINQ sẽ không tồn tại. Hậu quả: Không phải lúc nào cũng tốt hơn khi sử dụng PLINQ. – jason

Trả lời

2

PLinq là phiên bản song song của LINQ. Một số truy vấn có thể được thực hiện trên nhiều luồng và sau đó PLinq cho phép tăng hiệu suất.

Tuy nhiên, các truy vấn khác không thể được thực hiện song song hoặc sẽ cho kết quả sai nếu được thực hiện như vậy. Vì vậy, khi sử dụng PLinq là một cái gì đó bạn nên quyết định cho mỗi truy vấn và đảm bảo hiệu suất thực sự tăng lên.

MSDN có nhiều tài liệu về nó.

8

LINQ là tập hợp các công nghệ hoạt động cùng nhau để giải quyết một vấn đề tương tự - trong tất cả chúng bạn có nguồn dữ liệu (tệp xml hoặc tệp, nội dung cơ sở dữ liệu, tập hợp các đối tượng trong bộ nhớ) và bạn muốn truy xuất một số hoặc tất cả dữ liệu này và hành động theo cách nào đó. LINQ hoạt động trên sự tương đồng về điều đó bộ vấn đề như vậy mà:

var brithdays = from user in users where 
    user.dob.Date == DateTime.Today && user.ReceiveMails 
    select new{user.Firstname, user.Lastname, user.Email}; 
foreach(bdUser in birthdays) 
    SendBirthdayMail(bdUser.Firstname, bdUser.Lastname, bdUser.Email); 

Và (sử dụng rõ ràng của các lớp học và phương pháp LINQ quan với C# cú pháp truyền thống) tương đương:

var birthdays = users 
    .Where(user => user.dob.Date == DateTime.Today) 
    .Select(user => new{user.Firstname, user.Lastname, user.Email}); 
foreach(bdUser in birthdays) 
    SendBirthdayMail(bdUser.Firstname, bdUser.Lastname, bdUser.Email); 

Are cả hai ví dụ mã có thể hoạt động bất kể nó sẽ được chuyển thành các cuộc gọi cơ sở dữ liệu, phân tích cú pháp tài liệu xml hay tìm kiếm thông qua một mảng các đối tượng.

Sự khác biệt duy nhất là loại đối tượng users là gì. Nếu nó là một danh sách, mảng, hoặc bộ sưu tập đếm được khác, nó sẽ là linq-to-objects, nếu nó là một System.Data.Linq.Table nó sẽ là linq để sql. Trước đây sẽ dẫn đến các hoạt động trong bộ nhớ, sau này trong một truy vấn SQL mà sau đó sẽ được deserialised vào các đối tượng trong bộ nhớ càng muộn càng tốt.

Nếu đó là ParallelQuery - được tạo ra bằng cách gọi .AsParallel trên bộ sưu tập có sẵn trong bộ nhớ - thì truy vấn sẽ được thực hiện trong phần ghi nhớ, song song (phần lớn thời gian) để thực hiện theo nhiều luồng - cốt lõi bận rộn di chuyển công việc về phía trước.

Rõ ràng ý tưởng ở đây là nhanh hơn. Khi nó hoạt động tốt, nó hoạt động.

Có một số nhược điểm.

Trước tiên, luôn có một số chi phí để nhận được sự song song, ngay cả trong trường hợp kết thúc không thể song song. Nếu không có đủ công việc được thực hiện trên dữ liệu, chi phí này sẽ vượt quá bất kỳ lợi nhuận tiềm năng nào.

Thứ hai, lợi ích của việc xử lý song song phụ thuộc vào các lõi có sẵn. Với truy vấn không kết thúc việc chặn tài nguyên trên máy 4 lõi, về mặt lý thuyết bạn sẽ tăng tốc 4 lần (4 siêu luồng có thể cung cấp cho bạn nhiều hơn hoặc thậm chí ít hơn, nhưng có thể không phải 8 lần kể từ khi siêu luồng đôi của một số bộ phận của CPU không cho tăng rõ ràng hai lần). Với cùng một truy vấn trên một lõi đơn hoặc với ái lực bộ xử lý có nghĩa là chỉ có một lõi khả dụng (ví dụ: máy chủ web trong chế độ "web-vườn"), thì không có tăng tốc. Vẫn có thể đạt được nếu có chặn trên các nguồn tài nguyên, nhưng lợi ích phụ thuộc vào máy sau đó.

Thứ ba, nếu có bất kỳ tài nguyên chia sẻ (có thể là một kết quả thu được là ra để) được sử dụng trong một cách không threadsafe, nó có thể đi khá nặng sai với kết quả không chính xác, tai nạn vv

Thứ tư, nếu có một tài nguyên được chia sẻ đang được sử dụng theo cách an toàn và chủ đề an toàn đến từ khóa, có thể có đủ tranh chấp để trở thành nút cổ chai làm mất tất cả lợi ích từ việc song song. Thứ năm, nếu bạn có một máy bốn lõi làm việc trên nhiều hay ít thuật toán tương tự trên bốn chủ đề khác nhau (có lẽ trong tình huống máy khách-máy khách do bốn khách hàng, hoặc trên một tình huống máy tính để bàn từ một bộ tương tự nhiệm vụ cao hơn trong quá trình này), sau đó họ đang làm cho việc sử dụng tốt nhất các lõi đó. Tách công việc trong thuật toán lên để được xử lý trên tất cả bốn lõi có nghĩa là bạn đã di chuyển từ bốn chủ đề bằng cách sử dụng một lõi mỗi 16 chủ đề chiến đấu trên bốn lõi. Tốt nhất là nó sẽ giống nhau, và nhiều khả năng chi phí sẽ làm cho nó tồi tệ hơn một chút.

có thể vẫn là một chiến thắng lớn trong nhiều trường hợp, nhưng ở trên phải làm rõ rằng không phải lúc nào cũng vậy.

0

xem xét tránh anonymous types khi làm việc với PLINQ vì theo Threading in C#, by Joe Albahari:

kiểu nặc danh (là lớp học và do đó tham khảo các loại) phải chịu chi phí phân bổ đống dựa trên và thu gom rác thải tiếp theo.

(...)

phân bổ dựa trên stack rất parallelizable (như mỗi thread có stack riêng của mình), trong khi tất cả các chủ đề phải cạnh tranh cho các đống cùng - bởi một người quản lý bộ nhớ và rác thu đơn quản lý.

2

Cho rằng AsParallel minh bạch trả song song LINQ truy vấn, câu hỏi đặt ra: “Tại sao không chỉ đơn giản là Microsoft parallelize các nhà khai thác truy vấn tiêu chuẩn và làm PLINQ mặc định?”

Có một số lý do cho sự lựa chọn -in cách tiếp cận. Đầu tiên, để PLINQ hữu ích, phải có một lượng công việc tính toán hợp lý để nó có thể farm ra các luồng công nhân. Hầu hết các truy vấn LINQ to Objects thực hiện rất nhanh, và không chỉ song song sẽ là không cần thiết, nhưng chi phí phân vùng, đối chiếu và điều phối các chuỗi phụ có thể thực sự làm chậm mọi thứ.

Ngoài ra:

Đầu ra của truy vấn PLINQ (theo mặc định) có thể khác với truy vấn LINQ liên quan đến thứ tự phần tử.

Các nhà khai thác truy vấn sau đây ngăn chặn một truy vấn khỏi bị song song, trừ trường hợp các yếu tố nguồn đang ở vị trí chỉ mục ban đầu của họ:

Đưa, TakeWhile, Skip, và SkipWhile Các phiên bản được lập chỉ mục Select, SelectMany, và truy vấn elementAt Hầu hết các toán tử thay đổi vị trí chỉ mục của các phần tử (bao gồm cả các phần tử loại bỏ các phần tử, chẳng hạn như ở đâu). Điều này có nghĩa là nếu bạn muốn sử dụng các toán tử trước, chúng thường sẽ cần ở đầu truy vấn.

Các nhà khai thác truy vấn sau đây là parallelizable, nhưng sử dụng một chiến lược phân vùng đắt tiền mà đôi khi có thể chậm hơn so với xử lý tuần tự:

Tham gia, groupby, GroupJoin, biệt, Union, Intersect, và Trừ quá tải hạt giống Nhà điều hành tổng hợp trong các hóa thân chuẩn của chúng không song song - PLINQ cung cấp quá tải đặc biệt để giải quyết vấn đề này.

Khi nào nên sử dụng PLINQ Thật hấp dẫn để tìm kiếm các ứng dụng hiện tại của bạn cho các truy vấn LINQ và thử nghiệm song song chúng. Điều này thường không hiệu quả, bởi vì hầu hết các vấn đề mà LINQ rõ ràng là giải pháp tốt nhất có xu hướng thực thi rất nhanh và do đó không được hưởng lợi từ việc song song. Một cách tiếp cận tốt hơn là tìm một nút cổ chai chuyên sâu CPU và sau đó xem xét, “Điều này có thể được diễn tả như một truy vấn LINQ không?” (Một hiệu ứng phụ của việc tái cơ cấu đó là LINQ thường làm cho mã nhỏ hơn và dễ đọc hơn.)

PLINQ rất phù hợp với các vấn đề song song đáng xấu hổ. Nó cũng hoạt động tốt cho các tác vụ chặn có cấu trúc, chẳng hạn như gọi một số dịch vụ web cùng một lúc (xem chức năng Chặn cuộc gọi hoặc chức năng I/O-Intensive).

PLINQ có thể là một lựa chọn không tốt cho việc chụp ảnh, vì việc đối chiếu hàng triệu pixel thành một chuỗi đầu ra tạo ra một nút cổ chai. Thay vào đó, tốt hơn là ghi các pixel trực tiếp vào một mảng hoặc khối bộ nhớ không được quản lý và sử dụng lớp song song hoặc nhiệm vụ song song để quản lý đa luồng. (Có thể, tuy nhiên, để đánh bại kết quả đối chiếu bằng cách sử dụng ForAll. Làm như vậy có ý nghĩa nếu thuật toán xử lý hình ảnh tự nhiên tự vay cho LINQ.)

+2

Thật tuyệt nếu bạn đã đề cập đến nguồn; Luồng trong C#, bởi Joe Albahari: http://www.albahari.com/threading/part5.aspx#_PLINQ_Limitations – Rsh

Các vấn đề liên quan