2009-01-09 12 views
21

Gần đây tôi đã tìm thấy LINQ và yêu thích nó. Tôi tìm thấy rất nhiều trường hợp sử dụng nó có tính biểu cảm hơn nhiều so với phiên bản dài tay nhưng một đồng nghiệp đã thông qua một nhận xét về việc tôi lạm dụng công nghệ này mà giờ đây tôi đã tự đoán mình lần thứ hai. Đó là quan điểm của tôi rằng nếu một công nghệ hoạt động hiệu quả và mã là thanh lịch thì tại sao không sử dụng nó? Là sai đó? Tôi có thể dành thêm thời gian để viết ra các quy trình "dài tay" và trong khi mã kết quả có thể nhanh hơn vài ms, mã này gấp 2-3 lần và do đó gấp 2-3 lần khả năng có thể có lỗi.Nơi để vẽ đường - có thể yêu LINQ quá nhiều không?

Chế độ xem của tôi có sai không? Có nên Tôi đang viết mã của mình từ lâu hơn là sử dụng LINQ? Đây không phải là những gì LINQ được thiết kế cho?

Chỉnh sửa: Tôi đã nói về LINQ đối tượng, tôi không sử dụng LINQ to XML rất nhiều và tôi đã sử dụng LINQ to SQL nhưng tôi không quá say mê với những hương vị như LINQ đối tượng.

+0

bạn không chỉ định hương vị nào .... LINQ cho đối tượng? LINQ to XML? LINQ to SQL? Hai người đầu tiên tôi đồng ý với bạn, người cuối cùng tôi không sử dụng. –

Trả lời

19

Tôi phải đồng ý với quan điểm của bạn - nếu nó hiệu quả hơn để viết và thanh lịch thì một vài phần nghìn giây là gì. Viết thêm mã cho nhiều chỗ hơn cho các lỗi để leo vào và nó thêm mã mà cần phải được kiểm tra và hầu hết tất cả nó thêm mã để duy trì. Hãy suy nghĩ về những người sẽ đi vào phía sau bạn và duy trì mã của bạn - họ sẽ cảm ơn bạn đã viết thanh lịch dễ đọc mã lâu trước khi họ cảm ơn bạn đã viết mã đó là một vài ms nhanh hơn!

Hãy cẩn thận, mặc dù chi phí này của một vài ms có thể đáng kể khi bạn chụp ảnh lớn hơn. Nếu vài phần nghìn giây đó là một phần của một vòng lặp của hàng ngàn lần lặp lại, thì mili giây sẽ tăng nhanh.

+1

Đó cũng là những gì tôi nghĩ. Quan điểm của tôi là nó chỉ là lạm dụng nếu bạn đang đi ra khỏi con đường của bạn để tìm lý do để sử dụng nó ở những nơi sai – BobTheBuilder

1

Bạn đang trả lời câu hỏi của riêng mình bằng cách nói về viết mã 2-3 lần nhiều hơn cho một vài phút hoạt động. Ý tôi là, nếu miền vấn đề của bạn yêu cầu tăng tốc thì có, nếu không có lẽ không. Tuy nhiên, nó thực sự chỉ là một vài ms hiệu suất hay là nó> 5% hoặc> 10%. Đây là phán đoán giá trị dựa trên từng trường hợp riêng lẻ.

+0

Đó là điểm công bằng mà tôi giả sử - nếu bạn tăng từng vòng lặp của một chu kỳ vài ms thì nó sẽ giảm hiệu suất theo độ lớn - tuy nhiên trong trường hợp các vòng xử lý lớn, tôi có khả năng mã hóa hiệu suất trước sự thanh lịch nếu nó có nghĩa là một sự khác biệt đáng kể – BobTheBuilder

5

LINQ được cho là được sử dụng để lọc, sắp xếp, tổng hợp và thao tác dữ liệu từ nhiều nguồn khác nhau trực quan và biểu cảm nhất có thể. Tôi muốn nói, sử dụng nó bất cứ nơi nào bạn cảm thấy đó là cú pháp tidiest, biểu cảm nhất và tự nhiên nhất để làm những gì nó là bạn đang cố gắng làm, và không cảm thấy tội lỗi về nó.

Nếu bạn bắt đầu bung tài liệu, có thể là lúc xem xét lại vị trí của bạn.

+0

lol - vâng, nếu tôi đã bao giờ bắt đầu nhận được nóng bừng khi tôi nghĩ về lập trình tôi sẽ có một kỳ nghỉ: P – BobTheBuilder

+2

Vì vậy, các tài liệu nên được trên đầu trang? – CodeRedick

+1

Tôi nghĩ tài liệu giống như một người lập trình Bạn gái hay vợ - Theo lý thuyết, nó luôn luôn nên đến trước, nhưng thực tế nó hầu như bị lãng quên cho đến khi được nhắc nhở một cách khắc nghiệt rằng nó cần được ghi nhớ! – BobTheBuilder

5

Đó là trường hợp như thế này mà điều quan trọng là phải nhớ các quy tắc vàng của tối ưu hóa:

  1. Đừng Do It
  2. Đối với chuyên gia: Đừng làm điều đó chưa

Bạn hoàn toàn không nên không lo lắng về việc "lợi dụng" LINQ trừ khi bạn có thể xác định rõ ràng nguyên nhân của sự cố hiệu suất

+1

Tôi không thích điều này. Tôi có một cái nhìn hợp lý mà đi một cái gì đó như "Đừng sớm đi ra khỏi con đường của bạn để tối ưu hóa." Tuy nhiên, thái độ này có vẻ giống như "làm cho nó chậm như bạn biết làm thế nào để mã nó nhanh chóng." Nếu một người coi trọng vấn đề này, người ta sẽ luôn chọn cách tiếp cận ngây thơ. – BobbyShaftoe

5

Giống như bất cứ điều gì, nó có thể bị lạm dụng. Miễn là bạn tránh xa các quyết định kém rõ ràng, chẳng hạn như

var v = List.Where(...); 
for(int i = 0; i < v.Count(); i++) 
{...} 

và hiểu cách hoạt động khác nhau hoạt động, thì rất có thể sẽ không chậm hơn nhiều so với cách lâu dài. Theo Anders Hejlsburg (kiến trúc sư C#), trình biên dịch C# không đặc biệt giỏi trong việc tối ưu hóa các vòng lặp, tuy nhiên nó đang trở nên tốt hơn trong việc tối ưu hóa và song song các cây biểu thức.Theo thời gian, nó có thể hiệu quả hơn vòng lặp. Phiên bản ForEach của Danh sách <> thực sự nhanh như vòng lặp for, mặc dù tôi không thể tìm thấy liên kết chứng minh điều đó.

P.S. Sở thích cá nhân của tôi là ForEach <> 's anh em họ ít được biết đến IndexedForEach (sử dụng phương pháp khuyến nông)

List.IndexedForEach((p,i) => 
{ 
    if(i != 3) 
     p.DoSomething(i); 
}; 
+0

bạn có ý nghĩa gì bởi "thực hiện khác nhau"? – BobTheBuilder

+1

Xin chào Bob, Nhiều người trong số các câu lệnh LINQ không thực sự làm bất cứ điều gì cho đến khi bạn thử và sử dụng chúng. Ví dụ, List.Where() sẽ không được đánh giá cho đến khi Count() được gọi. Tuy nhiên, số đếm cuộc gọi sẽ đánh giá câu lệnh mỗi vòng lặp lặp lại, vì vậy câu lệnh LINQ được đánh giá mỗi vòng lặp lặp – Steve

+0

dẫn đến hiệu suất kém – Steve

8

của nó không thể yêu LINQ to Objects quá nhiều, đó là một công nghệ hoảng tuyệt vời!

Nhưng nghiêm túc, bất cứ điều gì làm cho mã của bạn dễ đọc, đơn giản để duy trì và thực hiện công việc đó, thì bạn sẽ ngớ ngẩn khi không sử dụng nó nhiều nhất có thể.

9

Có bạn có thể yêu LINQ quá nhiều - Single Statement LINQ RayTracer

Bạn vẽ đường kẻ ở đâu? Tôi muốn nói sử dụng LINQ nhiều như nó làm cho mã đơn giản và dễ đọc hơn.

Thời điểm phiên bản LINQ trở nên khó hiểu hơn, phiên bản không phải LINQ là thời gian để trao đổi và ngược lại. EDIT: Điều này chủ yếu áp dụng cho LINQ-To-Objects như các hương vị LINQ khác có lợi ích riêng của họ.

+0

Thiên Chúa của tôi rằng LINQ ví dụ là vô lý !!! Tôi phải nói rằng tôi không bao giờ có thời gian để giải mã tất cả những điều đó. Tôi đoán rằng vượt qua dòng của sự tỉnh táo. – BobTheBuilder

+2

vẽ đường kẻ? raytracer? Tôi nhận được trò đùa này. –

+0

Haha Nicholas, tốt nhất! Và tôi đồng ý, đó là một ví dụ vô lý, nhưng tôi nghĩ nó cũng là một thử thách rất thú vị để hiểu được nó và cách thức thực hiện. –

0

Nơi để vẽ đường?

Vâng, chúng tôi đã biết rằng bạn nên thực hiện quicksort in linq của riêng mình, ít nhất là so với chỉ sử dụng đơn đặt hàng của LINQ.

0

Tôi đã thấy rằng việc sử dụng LINQ đã tăng tốc độ phát triển của tôi và giúp dễ dàng tránh những sai lầm ngu ngốc mà vòng lặp có thể giới thiệu. Tôi đã có trường hợp mà hiệu suất của LINQ là nghèo, nhưng đó là khi tôi đã sử dụng nó để những thứ như lấy dữ liệu cho một tập tin excel từ một cấu trúc cây có hàng triệu nút.

0

Trong khi tôi thấy có một quan điểm mà LINQ có thể làm cho một tuyên bố khó đọc hơn, tôi nghĩ rằng điều này còn quá lớn so với thực tế là các phương pháp của tôi bây giờ liên quan chặt chẽ đến các vấn đề mà họ đang giải quyết và không chi tiêu thời gian hoặc bao gồm các vòng tìm kiếm hoặc các lớp lộn xộn với các chức năng tìm kiếm chuyên dụng.

Phải mất một chút thời gian để làm quen với việc làm việc với LINQ, vì tra cứu vòng lặp và những thứ tương tự, đã là tùy chọn chính quá lâu. Tôi nhìn LINQ như một loại đường cú pháp khác có thể thực hiện nhiệm vụ tương tự một cách thanh lịch hơn. Ngay bây giờ, tôi vẫn đang tránh nó trong quá trình xử lý nghiêm trọng nhiệm vụ mã - nhưng đó là chỉ cho đến khi hiệu suất cải thiện như LINQ phát triển.

0

Mối quan tâm duy nhất của tôi về LINQ là thực hiện các phép nối của nó.

Như tôi đã xác định khi cố gắng trả lời this question (và được xác nhận here), mã LINQ tạo để thực hiện kết nối là (nhất thiết, tôi đoán) ngây thơ: cho mỗi mục trong danh sách, tham gia thực hiện tìm kiếm tuyến tính thông qua đã tham gia danh sách để tìm các kết quả phù hợp.

Việc thêm tham gia vào truy vấn LINQ về cơ bản biến thuật toán thời gian tuyến tính thành thuật toán bậc hai. Ngay cả khi bạn nghĩ rằng tối ưu hóa sớm là gốc rễ của tất cả các điều ác, nhảy từ O (n) đến O (n^2) sẽ cho bạn tạm dừng. (Đó là O (n^3) nếu bạn tham gia thông qua một mục đã tham gia vào một bộ sưu tập khác.)

Nó tương đối dễ dàng để giải quyết vấn đề này.Ví dụ: truy vấn này:

var list = from pr in parentTable.AsEnumerable() 
join cr in childTable.AsEnumerable() on cr.Field<int>("ParentID") equals pr.Field<int>("ID") 
where pr.Field<string>("Value") == "foo" 
select cr; 

tương tự như cách bạn tham gia hai bảng trong SQL Server. Nhưng nó vô cùng hiệu quả trong LINQ: đối với mỗi hàng cha mà mệnh đề where trả về, truy vấn quét toàn bộ bảng con. (Ngay cả khi bạn đang tham gia vào một lĩnh vực unindexed, SQL Server sẽ xây dựng một hashtable để tăng tốc độ tham gia nếu nó có thể Đó là một chút bên ngoài lớp trả LINQ của..)

Truy vấn này, tuy nhiên:

string fk = "FK_ChildTable_ParentTable"; 
var list = from cr in childTable.AsEnumerable() 
where cr.GetParentRow(fk).Field<string>("Value") == "foo" 
select cr; 

cho kết quả tương tự, nhưng nó chỉ quét bảng con một lần duy nhất.

Nếu bạn đang sử dụng LINQ cho đối tượng, các vấn đề tương tự sẽ áp dụng: nếu bạn muốn tham gia hai bộ sưu tập với bất kỳ kích thước đáng kể nào, có thể bạn sẽ cần cân nhắc triển khai phương pháp hiệu quả hơn để tìm đối tượng đã tham gia, ví dụ:

Dictionary<Foo, Bar> map = buildMap(foos, bars); 
var list = from Foo f in foos 
where map[f].baz == "bat" 
select f; 
+1

Điều này hoàn toàn không đúng sự thật. Toán tử join LINQ tải tất cả các phần tử trong chuỗi bên trong vào một tra cứu dựa trên hashtable hiệu quả. Ví dụ cụ thể của bạn là không hiệu quả nhẹ trong đó bạn đang lọc SAU KHI tham gia (thay vì trước) nhưng tham gia chính nó là hoàn toàn hiệu quả. –

3

LINQ có thể giống như nghệ thuật. Tiếp tục sử dụng nó để làm cho mã đẹp.

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