Theo thứ tự các bảng hiệu quả nhất về thời gian kết xuất và hiệu suất?


127

Có nhiều lần khi nhiều bảng điều khiển phù hợp với bố cục tôi muốn, tuy nhiên tôi biết có sự khác biệt về thời gian kết xuất cho các loại bảng khác nhau.

Ví dụ: MSDN nói rằng

Một tương đối đơn giản Panel, chẳng hạn như Canvas, có thể có hiệu suất tốt hơn đáng kể so với phức tạp hơn Panel, chẳng hạn như Grid.

Vậy về mặt thời gian và hiệu năng kết xuất, bảng WPF theo thứ tự nào là hiệu quả nhất?

Bảng WPF:

  • Canvas
  • DockPanel
  • Grid
  • UniformGrid
  • StackPanel
  • WrapPanel
  • VirtualizingPanel / VirtualizingStackPanel

Tôi khá chắc chắn rằng tôi đã thấy một danh sách này ở đâu đó trên mạng, nhưng tôi không thể tìm thấy nó ngay bây giờ.

Câu trả lời lý tưởng mà tôi đang tìm kiếm sẽ cung cấp cho tôi một danh sách các bảng theo thứ tự chúng sẽ hiển thị nhanh nhất. Tôi hiểu số lượng trẻ em là một yếu tố lớn trong hiệu quả của các bảng, vì vậy vì câu hỏi này, giả sử mỗi bảng chỉ có một Label/ TextBoxcặp.

Ngoài ra, tôi muốn có một danh sách các trường hợp ngoại lệ, chẳng hạn như các bảng cụ thể hoạt động tốt hơn các bảng khác dựa trên các điều kiện nhất định.

Cập nhật

Để tóm tắt dựa trên câu trả lời được chấp nhận bên dưới, hiệu suất của bảng điều khiển dựa trên số lượng và bố cục của các mục con, tuy nhiên, nói chung, danh sách từ nhanh nhất đến chậm nhất là:

  • Canvas
  • StackPanel
  • WrapPanel
  • DockPanel
  • Grid

Ngoài ra, a VirtualizingPanel/ VirtualizingStackPanelnên luôn được sử dụng nếu có nhiều vật phẩm không luôn phù hợp trên màn hình.

Tôi thực sự khuyên bạn nên đọc câu trả lời được chấp nhận bên dưới để biết thêm chi tiết trước khi chỉ chọn một mục từ danh sách này.


Có phải là ngây thơ khi cho rằng các bảng ảo hóa sẽ luôn hoạt động tốt hơn so với các bảng không ảo hóa?
BoltClock

@BoltClock Tôi nghĩ rằng nó phụ thuộc vào số lượng nội dung không hiển thị trong bảng điều khiển. Nếu có nhiều mục không nhìn thấy được, VirtualizingStackPanelchắc chắn sẽ hoạt động tốt hơn, nhưng nếu tất cả các mục được hiển thị trong bảng điều khiển hiển thị hơn tôi nghĩ tốt hơn là sử dụng bảng thông thường.
Rachel

Cảm ơn. Điều đó có nghĩa là nó sẽ là một vật phẩm ảo hóa lãng phí, khi tất cả chúng sẽ hiển thị.
BoltClock

Khác với ảo hóa chúng có các tính năng khác nhau hoặc chúng sẽ không phải là các điều khiển riêng biệt. Tôi đi với những gì cung cấp giao diện người dùng tốt nhất cho khách hàng.
paparazzo

1
Bạn có chắc chắn có một sự khác biệt đáng chú ý (ngoài Ảo hóa) không? Tất cả những gì họ phải làm là thực hiện một thuật toán bố trí tương đối nhẹ. Tiny so với tất cả các kết xuất sẽ làm theo. Đã nói rằng, Grid có thể sẽ là chậm nhất (chia tỷ lệ).
Henk Holterman

Câu trả lời:


130

Tôi nghĩ việc mô tả các đặc tính hiệu suất của từng bảng sẽ ngắn gọn và dễ hiểu hơn là cố gắng đưa ra một so sánh hiệu suất tương đối tuyệt đối.

WPF thực hiện hai lần khi hiển thị nội dung: Đo và Sắp xếp. Mỗi bảng có các đặc tính hiệu suất khác nhau cho mỗi hai lượt đi này.

Hiệu suất của phương pháp đo bị ảnh hưởng nhiều nhất bởi khả năng của bảng điều khiển kéo dài bằng cách sử dụng sắp xếp (hoặc Tự động trong trường hợp Grid) và sau đó là số trẻ em được kéo dài hoặc tự động kích thước. Hiệu suất của Arrange pass bị ảnh hưởng bởi sự phức tạp của sự tương tác giữa vị trí bố trí của những đứa trẻ khác nhau và sau đó tất nhiên là số lượng trẻ em.

Đôi khi các bảng đã cho không dễ dàng cho vay theo bố cục cần thiết. Tôi đã tạo một điều khiển cần một số lượng mục tùy ý cho mỗi mục được định vị ở một tỷ lệ nhất định của không gian có sẵn. Không có điều khiển mặc định nào làm điều này. Cố gắng làm cho họ làm điều này (thông qua ràng buộc với kích thước thực tế của cha mẹ) dẫn đến hiệu suất khủng khiếp. Tôi đã tạo một bảng bố trí dựa trên Canvas đạt được kết quả mong muốn với công việc tối thiểu (tôi đã sao chép nguồn cho khung vẽ và sửa đổi khoảng 20 dòng của nó).

Tấm có sẵn:

  • Tranh sơn dầu

    Xác định một khu vực trong đó bạn có thể định vị rõ ràng các phần tử con theo tọa độ so với vùng Canvas.

    Canvas có hiệu suất tốt nhất trong tất cả các bảng để sắp xếp vượt qua vì mỗi mục được gán tĩnh một vị trí. Pass đo cũng có hiệu suất tuyệt vời vì không có khái niệm kéo dài trong bảng điều khiển này; mỗi đứa trẻ chỉ cần sử dụng kích thước bản địa của nó.

  • DockPanel

    Xác định một khu vực trong đó bạn có thể sắp xếp các phần tử con theo chiều ngang hoặc chiều dọc, tương đối với nhau.

    Dockpanel có sơ đồ bố trí rất đơn giản trong đó các mục được thêm từng cái một so với mục trước được thêm vào. Theo mặc định, chiều cao hoặc chiều rộng được xác định bởi kích thước gốc của vật phẩm (dựa trên Top / bottom so với trái / phải tương ứng) và hướng khác được xác định bởi thuộc Docktính nếu chiều rộng hoặc chiều cao không được xác định. Đo trung bình đến nhanh và vượt qua sắp xếp trung bình đến nhanh.

  • Lưới

    Xác định vùng lưới linh hoạt bao gồm các cột và hàng.

    Đây có thể là bảng điều khiển chuyên sâu hiệu suất nhất nếu sử dụng kích thước tỷ lệ hoặc kích thước tự động được sử dụng. Tính kích thước mục con có thể là sự kết hợp phức tạp của kích thước gốc của mục và bố cục được chỉ định bởi lưới. Bố cục cũng phức tạp nhất trong tất cả các bảng. Hiệu suất chậm đến trung bình cho vượt qua đo và hiệu suất chậm đến trung bình cho vượt qua sắp xếp.

  • StackPanel

    Sắp xếp các phần tử con thành một dòng duy nhất có thể được định hướng theo chiều ngang hoặc chiều dọc.

    StackPanel đo lường con cái của nó bằng cách sử dụng kích thước gốc hoặc kích thước tương đối theo hướng ngược lại với hướng của nó và kích thước gốc theo hướng định hướng của nó (căn chỉnh không có gì theo hướng này). Điều này làm cho nó một trình diễn trung cấp trong lĩnh vực này. Pass sắp xếp đơn giản, chỉ cần sắp xếp các mục theo thứ tự. Có lẽ hiệu suất tốt thứ hai cho vượt qua này. Hiệu suất trung bình cho vượt qua đo và hiệu suất nhanh cho vượt qua bố trí.

  • VirtualizingPanel

    Cung cấp một khung cho các thành phần Bảng điều khiển ảo hóa việc thu thập dữ liệu con của chúng. Đây là một lớp trừu tượng.

    Một lớp cơ sở để thực hiện bảng ảo hóa của riêng bạn. Chỉ tải các mục có thể nhìn thấy để ngăn chặn việc sử dụng bộ nhớ và bộ xử lý không cần thiết. NHIỀU hiệu suất cao hơn cho các bộ các mặt hàng. Có lẽ ít hiệu suất hơn cho các mục phù hợp trên màn hình do kiểm tra giới hạn. SDK chỉ cung cấp một lớp con này VirtualizingStackPanel.

  • WrapPanel

    Định vị các phần tử con ở vị trí liên tiếp từ trái sang phải, ngắt nội dung sang dòng tiếp theo ở cạnh của hộp chứa. Thứ tự tiếp theo xảy ra tuần tự từ trên xuống dưới hoặc phải sang trái, tùy thuộc vào giá trị của thuộc tính Định hướng.

    Pass đo là một đường chuyền hơi phức tạp trong đó mục lớn nhất cho một hàng cụ thể xác định chiều cao của hàng và sau đó mỗi mục trên hàng đó sử dụng chiều cao riêng của nó (nếu có) hoặc chiều cao của hàng. Việc bố trí vượt qua rất đơn giản, đặt từng mục một lần lượt trên một hàng và sau đó tiếp tục lên hàng tiếp theo khi không đủ chỗ cho mục tiếp theo. Đo hiệu suất trung bình vượt qua. Hiệu suất trung bình đến nhanh cho việc sắp xếp vượt qua.

Người giới thiệu:

Sử dụng Bảng hiệu quả nhất khi có thể

Độ phức tạp của quy trình bố trí trực tiếp dựa trên hành vi bố trí của các thành phần có nguồn gốc từ Bảng điều khiển bạn sử dụng. Ví dụ: điều khiển Grid hoặc StackPanel cung cấp nhiều chức năng hơn so với điều khiển Canvas. Cái giá cho sự gia tăng lớn hơn về chức năng này là sự gia tăng lớn hơn về chi phí hiệu năng. Tuy nhiên, nếu bạn không yêu cầu chức năng mà điều khiển Grid cung cấp, bạn nên sử dụng các lựa chọn thay thế ít tốn kém hơn, chẳng hạn như Canvas hoặc bảng điều khiển tùy chỉnh.

Từ tối ưu hóa hiệu suất: Bố cục và thiết kế

Hệ thống bố trí hoàn thành hai đường chuyền cho mỗi thành viên của bộ sưu tập Trẻ em, đường chuyền đo và đường chuyền sắp xếp. Mỗi Bảng điều khiển con cung cấp các phương thức Số đo riêng và ArrangeOverride riêng để đạt được hành vi bố cục cụ thể của riêng nó.

Trong quá trình đo, mỗi thành viên của bộ sưu tập Trẻ em được đánh giá. Quá trình bắt đầu với một cuộc gọi đến phương pháp Đo. Phương thức này được gọi trong khi triển khai phần tử Bảng điều khiển chính và không phải gọi rõ ràng để bố trí xảy ra.

Đầu tiên, các thuộc tính kích thước gốc của UIE bổ sung được đánh giá, chẳng hạn như Clip và Hiển thị. Điều này tạo ra một giá trị có tên là ràng buộc kích thước được truyền cho Đo lường.

Thứ hai, các thuộc tính khung được xác định trên FrameworkEuity được xử lý, điều này ảnh hưởng đến giá trị của ràng buộc. Các thuộc tính này thường mô tả các đặc điểm kích thước của UIE bổ sung bên dưới, chẳng hạn như Chiều cao, Chiều rộng, Lề và Kiểu. Mỗi thuộc tính này có thể thay đổi không gian cần thiết để hiển thị phần tử. Đo lường sau đó được gọi với ràng buộc kích thước như là một tham số.

Lưu ý Có sự khác biệt giữa các thuộc tính của Chiều cao và Chiều rộng và ActualHeight và ActualWidth. Ví dụ: thuộc tính ActualHeight là một giá trị được tính toán dựa trên các đầu vào chiều cao khác và hệ thống bố trí. Giá trị được đặt bởi chính hệ thống bố trí, dựa trên đường truyền kết xuất thực tế và do đó có thể bị tụt lại một chút so với giá trị được đặt của các thuộc tính, chẳng hạn như Chiều cao, là cơ sở của thay đổi đầu vào. Vì ActualHeight là một giá trị được tính toán, bạn nên lưu ý rằng có thể có nhiều thay đổi hoặc báo cáo thay đổi đối với nó do kết quả của các hoạt động khác nhau của hệ thống bố trí. Hệ thống bố trí có thể tính toán không gian đo cần thiết cho các phần tử con, các ràng buộc của phần tử cha, v.v. Mục tiêu cuối cùng của việc vượt qua biện pháp là để đứa trẻ xác định DesiredSize của nó, xảy ra trong cuộc gọi biện pháp. Giá trị DesiredSize được lưu trữ bằng Biện pháp để sử dụng trong quá trình sắp xếp nội dung.

Pass sắp xếp bắt đầu bằng một cuộc gọi đến phương thức Sắp xếp. Trong quá trình sắp xếp, phần tử Bảng điều khiển cha mẹ tạo ra một hình chữ nhật đại diện cho giới hạn của con. Giá trị này được truyền cho phương thức ArrangeCore để xử lý.

Phương thức ArrangeCore đánh giá DesiredSize của đứa trẻ và đánh giá bất kỳ lề bổ sung nào có thể ảnh hưởng đến kích thước được hiển thị của phần tử. ArrangeCore tạo ra sortSize, được truyền cho phương thức ArrangeOverride của Panel dưới dạng tham số. ArrangeOverride tạo ra FinalSize của trẻ. Cuối cùng, phương thức ArrangeCore thực hiện đánh giá cuối cùng các thuộc tính bù, chẳng hạn như lề và căn chỉnh, và đặt con trong khe bố trí của nó. Đứa trẻ không phải (và thường xuyên không) lấp đầy toàn bộ không gian được phân bổ. Kiểm soát sau đó được trả về Bảng điều khiển chính và quá trình bố trí hoàn tất.

Từ đo lường và sắp xếp trẻ em


1
Đáp lại bình luận đã bị xóa: Tôi không bao gồm các số liệu vì chúng sẽ không hữu ích. Có quá nhiều kết hợp cho một bảng tính là hữu ích. Một phương pháp hữu ích hơn để tối ưu hóa hiệu suất sẽ là sử dụng sự hiểu biết chung để chọn bảng bố cục ban đầu và sau đó tối ưu hóa khi cần thiết từ đó bằng cách sử dụng phân tích tình huống thực tế.
N_A

Cảm ơn bạn, lời giải thích của bạn về cách các bảng WPF thực sự được hiển thị và hiệu suất Đo / Sắp xếp của mỗi bảng tốt hơn nhiều so với những gì tôi đã yêu cầu :)
Rachel

@mydogisbox Tôi không thấy UniformGridtrong danh sách của bạn ở bất cứ đâu. Bạn có thể cập nhật câu trả lời của mình với bảng điều khiển đó không và ước tính hiệu suất Đo / Sắp xếp liên quan đến các loại bảng khác?
Rachel

1
@Rachel UniformGridKhông dành cho sử dụng trong bố trí ứng dụng. Xem "Các thành phần bảng điều khiển" tại đây: msdn.microsoft.com/en-us/l Library / ms754152.aspx để biết thêm thông tin. Tốc độ khôn ngoan nên nhanh hơn một DockPanelchút và chậm hơn một chút Canvas.
N_A

12

Có lẽ điều này sẽ giúp bạn.

Không chỉ cho các bảng mà còn cho mọi ứng dụng bạn muốn thực hiện trong WPF.

Nó kết luận hiệu suất bản vẽ và đo lường WPF.

Nó cũng có một ứng dụng thử nghiệm bản vẽ, kết quả và thông tin kết luận cho các hệ điều hành khác nhau mà bạn muốn nhắm mục tiêu.


8

Các bảng bạn đề cập là các bảng Bố cục, do đó, tổng quan ngắn gọn về hệ thống bố cục cho thấy có thể nó sẽ không chỉ là một danh sách đơn giản của bảng hiệu quả nhất mà là cách bạn sử dụng các bảng có ảnh hưởng lớn nhất đến hiệu quả và hiệu suất.

Giao diệnSystem_Overview :

Đơn giản nhất, bố cục là một hệ thống đệ quy dẫn đến một yếu tố có kích thước, vị trí và được vẽ. Cụ thể hơn, bố cục mô tả quá trình đo lường và sắp xếp các thành viên của bộ sưu tập Trẻ em của thành phần Bảng điều khiển. Bố cục là một quá trình chuyên sâu. Bộ sưu tập Trẻ em càng lớn, số lượng tính toán phải thực hiện càng nhiều. Độ phức tạp cũng có thể được giới thiệu dựa trên hành vi bố trí được xác định bởi thành phần Bảng điều khiển sở hữu bộ sưu tập. Một Bảng tương đối đơn giản, chẳng hạn như Canvas, có thể có hiệu suất tốt hơn đáng kể so với Bảng phức tạp hơn, chẳng hạn như Lưới.

Mỗi khi một đứa trẻ UIE bổ sung thay đổi vị trí của nó, nó có khả năng kích hoạt một đường chuyền mới bằng hệ thống bố trí. Do đó, điều quan trọng là phải hiểu các sự kiện có thể gọi hệ thống bố trí, vì việc gọi không cần thiết có thể dẫn đến hiệu suất ứng dụng kém. Dưới đây mô tả quá trình xảy ra khi hệ thống bố trí được gọi.

1. Một UIEuity con bắt đầu quá trình bố trí bằng cách trước tiên có các thuộc tính cốt lõi của nó được đo.

2. Các thuộc tính kích thước được xác định trên FrameworkEuity được đánh giá, chẳng hạn như Chiều rộng, Chiều cao và Ký quỹ.

3. Logic dành riêng cho bảng điều khiển được áp dụng, chẳng hạn như hướng Dock hoặc Định hướng xếp chồng.

4. Nội dung được sắp xếp sau khi tất cả trẻ em đã được đo.

5. Bộ sưu tập Trẻ em được vẽ trên màn hình.

6. Quá trình được gọi lại nếu Trẻ em bổ sung được thêm vào bộ sưu tập, Giao diện bố cục được áp dụng hoặc phương thức UpdateLayout được gọi.

Xem LayoutSystem_Measure_Arrange để biết thêm thông tin về việc đo lường và sắp xếp trẻ em

LayoutSystem_Performance :

Bố cục là một quá trình đệ quy. Mỗi phần tử con trong bộ sưu tập Trẻ em được xử lý trong mỗi lần gọi hệ thống bố trí. Do đó, nên tránh kích hoạt hệ thống bố trí khi không cần thiết. Những cân nhắc sau đây có thể giúp bạn đạt được hiệu suất tốt hơn.

Lưu ý rằng những thay đổi giá trị thuộc tính sẽ buộc cập nhật đệ quy bởi hệ thống bố trí.

Các thuộc tính phụ thuộc có giá trị có thể khiến hệ thống bố trí được khởi tạo được đánh dấu bằng các cờ công khai. AffectsMeasure và AffectsArrange cung cấp manh mối hữu ích về việc thay đổi giá trị thuộc tính sẽ buộc cập nhật đệ quy bởi hệ thống bố trí. Nói chung, bất kỳ thuộc tính nào có thể ảnh hưởng đến kích thước của hộp giới hạn của một thành phần nên được đặt cờ AffectsMeasure thành đúng. Để biết thêm thông tin, xem Tổng quan về thuộc tính phụ thuộc.

Khi có thể, hãy sử dụng RenderTransform thay vì LayoutTransform.

Một LayoutTransform có thể là một cách rất hữu ích để ảnh hưởng đến nội dung của giao diện người dùng (UI). Tuy nhiên, nếu hiệu ứng của biến đổi không phải tác động đến vị trí của các phần tử khác, tốt nhất là sử dụng RenderTransform thay thế, vì RenderTransform không gọi hệ thống bố cục. LayoutTransform áp dụng chuyển đổi của nó và buộc cập nhật bố cục đệ quy để giải thích cho vị trí mới của phần tử bị ảnh hưởng.

Tránh các cuộc gọi không cần thiết đến UpdateLayout.

Phương thức UpdateLayout buộc cập nhật bố cục đệ quy và thường không cần thiết. Trừ khi bạn chắc chắn rằng cần phải cập nhật đầy đủ, hãy dựa vào hệ thống bố trí để gọi phương thức này cho bạn.

Khi làm việc với bộ sưu tập Trẻ em lớn, hãy cân nhắc sử dụng VirtualizingStackPanel thay vì StackPanel thông thường.

Bằng cách ảo hóa bộ sưu tập con, VirtualizingStackPanel chỉ giữ các đối tượng trong bộ nhớ hiện nằm trong ViewPort của cha mẹ. Kết quả là, hiệu suất được cải thiện đáng kể trong hầu hết các kịch bản.

Tối ưu hóa hiệu suất: Bố cục và thiết kế : Bài viết này đi sâu vào chi tiết về cách xây dựng cây hiệu quả và đưa ra một danh sách đơn giản các bảng điều khiển dựa trên độ phức tạp của chúng

Canvas (ít phức tạp nhất = hiệu quả hơn và hiệu suất tốt hơn)

Lưới

Các bảng khác (phức tạp hơn = hiệu quả kém hơn và hiệu suất kém hơn)

Các cân nhắc về hiệu suất khác cần chú ý: Cách cải thiện tốc độ kết xuất UI WPF

  1. Cache mọi thứ. Bàn chải, màu sắc, hình học, văn bản định dạng, Glyphs. .
  2. Freeze Freezable, nếu bạn dự định sử dụng nó trong một thời gian dài. Đặc biệt là hình học. Hình học không phức tạp thực hiện HitTest cực kỳ chậm.
  3. Chọn cách nhanh nhất để kết xuất của mỗi nguyên thủy. Ví dụ: có khoảng 6 cách hiển thị văn bản, nhưng nhanh nhất là DrawContext.DrawGlyphs.
  4. Cho phép tái chế container. Ảo hóa mang lại rất nhiều cải tiến hiệu suất, nhưng các container sẽ được xử lý và tạo lại, đây là mặc định. Nhưng bạn có thể đạt được hiệu suất cao hơn bằng cách tái chế các thùng chứa bằng cách đặt VirtualizingStackPanel.VirtualizationMode = "Tái chế"
  5. Từ đây : Không có giới hạn thực tế nào cho số lượng lồng mà ứng dụng của bạn có thể hỗ trợ, tuy nhiên, nói chung, tốt nhất là giới hạn ứng dụng của bạn chỉ sử dụng những bảng thực sự cần thiết cho bố cục mong muốn của bạn. Trong nhiều trường hợp, một phần tử Grid có thể được sử dụng thay cho các bảng lồng nhau do tính linh hoạt của nó như là một thùng chứa bố cục. Điều này có thể tăng hiệu suất trong ứng dụng của bạn bằng cách giữ các yếu tố không cần thiết ra khỏi cây.

2
Câu trả lời này bao gồm gần như hoàn toàn việc sao chép và dán từ các nguồn khác, một số không được phân bổ. Sẽ tốt hơn nhiều nếu bạn cắt nó xuống chỉ còn các phần có liên quan, quy kết chính xác tất cả các nguồn và cố gắng trả lời trực tiếp hơn câu hỏi.
N_A

2
@mydogisbox Câu trả lời là tổng hợp thông tin, nhiều trang web bạn đã sử dụng trong câu trả lời của mình, tôi có thể thêm vào. Để không xem xét các khía cạnh khác làm thay đổi hiệu suất có thể dẫn đến một câu trả lời không đầy đủ hoặc người hỏi vẫn có thêm câu hỏi, vì vậy tôi đã chọn đưa chúng vào. Trong khi Rachel với một đại diện 21,7K tuyệt vời và nhiều kinh nghiệm về WPF có thể đã biết thông tin này, những người đang xem câu hỏi này có thể mong muốn thông tin bổ sung và liên quan này cùng với câu trả lời.
Erick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.