2009-01-28 87 views
8

Tôi tự hỏi loại kỹ thuật tối ưu hóa nào mà mọi người thường sử dụng hiện nay. Tôi đã thấy mọi người làm bộ nhớ đệm mọi lúc với từ điển và tất cả. Là không gian giao dịch cho tốc độ cách duy nhất để đi?Kỹ thuật tối ưu hóa trong C#

+0

Bạn có thể cụ thể hơn về trường hợp bạn có trong đầu không? "Tối ưu hóa" là một danh mục rộng lớn. – Larsenal

+0

Vâng, cách mở rộng. bạn có câu hỏi riêng không? –

+0

Chỉ cần tự hỏi nếu có cách nào để tối ưu hóa mã khác với việc sử dụng bộ nhớ đệm với từ điển. – Tom

Trả lời

2

Tùy thuộc vào rất nhiều thứ.

Ví dụ, khi bộ nhớ trở thành sự cố và nhiều đối tượng tạm thời đang được tạo, tôi có xu hướng sử dụng các nhóm đối tượng. (Có một bộ thu rác không phải là một lý do để không chăm sóc phân bổ bộ nhớ). Nếu tốc độ là những gì quan trọng thì tôi có thể sử dụng con trỏ không an toàn để làm việc với các mảng.

Dù bằng cách nào, nếu bạn thấy mình đang gặp khó khăn quá nhiều với các kỹ thuật tối ưu hóa trong ứng dụng mạng C# /. Có thể bạn đã chọn sai ngôn ngữ/nền tảng.

1

Nói chung, hãy đảm bảo bạn hiểu độ phức tạp của các thuật toán khác nhau và sử dụng kiến ​​thức đó để chọn triển khai của bạn một cách khôn ngoan.

Đối với .NET nói riêng, bài viết này đi sâu vào chi tiết về tối ưu hóa mã được triển khai cho CLR (mặc dù nó cũng có liên quan đến Java hoặc bất kỳ nền tảng hiện đại nào khác) và là một trong những hướng dẫn tốt nhất mà tôi từng đọc :

http://msdn.microsoft.com/en-us/library/ms973852.aspx

Để chưng cất bài viết thành một câu: Không có gì ảnh hưởng đến tốc độ của một ứng dụng .NET (với các thuật toán hợp lý) hơn so với bộ nhớ dấu chân của các đối tượng của nó. Hãy rất cẩn thận để giảm thiểu mức tiêu thụ bộ nhớ của bạn.

4

Thường có vấn đề với các thuật toán, thường là khi một cái gì đó đắt tiền được thực hiện bên trong một vòng lặp. Nói chung, điều đầu tiên bạn làm là hồ sơ ứng dụng của bạn, sẽ cho bạn biết (các) phần chậm nhất của ứng dụng. Nói chung, những gì bạn làm để tăng tốc ứng dụng của bạn phụ thuộc vào những gì bạn tìm thấy. Ví dụ, nếu ứng dụng của bạn bắt chước một hệ thống tập tin, có thể bạn đang gọi cơ sở dữ liệu đệ quy để di chuyển lên cây (ví dụ). Bạn có thể tối ưu hóa trường hợp đó bằng cách thay đổi các cuộc gọi đệ quy đó thành một cuộc gọi cơ sở dữ liệu phẳng mà trả về tất cả dữ liệu trong một cuộc gọi.

Một lần nữa, câu trả lời là, như mọi khi, 'nó phụ thuộc'. Tuy nhiên, bạn có thể tìm thêm ví dụ và lời khuyên trong Rico Mariani's blog (duyệt lại vài năm, khi tiêu điểm của anh ấy đã thay đổi):

+0

Việc lập hồ sơ cho bạn ứng dụng cụ thể có lẽ là lời khuyên tốt duy nhất. Hồ sơ, xem những gì đang chậm (hoặc hogging bộ nhớ), và cố gắng để cắt nó xuống. – Kibbee

+0

Tôi đang thực sự tìm kiếm các ví dụ tốt. Mọi người sử dụng memoization (caching một lần nữa) để thu thập. 1 cho ví dụ về cơ sở dữ liệu. – Tom

3

Thực sự đó là sự lựa chọn của bạn về thuật toán. Thông thường không có "viên đạn bạc" để tối ưu hóa. Ví dụ: sử dụng StringBuilder thay vì nối có thể làm cho mã của bạn nhanh hơn đáng kể, nhưng có sự cân bằng. Nếu bạn không ghép các bộ dây lớn, bộ nhớ và thời gian cần thiết để khởi tạo StringBuilder là tồi tệ hơn chỉ sử dụng nối thường xuyên. Có rất nhiều ví dụ về điều này trong suốt khuôn khổ, chẳng hạn như bộ nhớ đệm từ điển như bạn đã đề cập trong câu hỏi của mình.

Việc tối ưu hóa chung duy nhất mà bạn thực sự có thể thực hiện tìm hiểu và áp dụng cho mã hóa của bạn trong suốt cả ngày là hiệu suất trúng từ boxing/unboxing (heap so với stack). Để làm điều này bạn cần phải tìm hiểu những gì nó về và làm thế nào để tránh, hoặc làm giảm nhu cầu để làm điều đó.

Tài liệu MSDN của Microsoft có 2 bài viết về hiệu suất cung cấp nhiều kỹ thuật mục đích chung tốt để sử dụng (chúng thực sự chỉ là các phiên bản khác nhau của cùng một bài viết).

+0

StringBuilder là một trình tối ưu hóa dễ triển khai khi làm việc với tòa nhà lặp lại. – Pat

1

Tôi muốn giới thiệu Effective C# bởi Bill Wagner (first editionsecond edition). Anh ta đi qua một số cấu trúc và kỹ thuật ngôn ngữ và giải thích cái nào nhanh hơn và tại sao. Anh ấy cũng thực hiện rất nhiều phương pháp hay nhất.

Thường xuyên hơn không, tuy nhiên, tối ưu hóa thuật toán của bạn sẽ cung cấp cho bạn kết quả tốt hơn nhiều so với sử dụng bất kỳ loại kỹ thuật ngôn ngữ/tối ưu hóa nào.

+0

Chính xác những gì tôi có thể nói - đây là nơi tôi sẽ vượt qua lần đầu tiên. – mmr

2

tôi sẽ gợi ý dưới đây

1. Biết khi nào nên sử dụng StringBuilder

Bạn phải đã nghe trước đó một đối tượng StringBuilder là nhanh hơn nhiều ở phụ thêm chuỗi với nhau hơn các loại chuỗi bình thường.

The thing is StringBuilder is faster mostly with big strings. This means if you have a loop that will add to a single string for many iterations then a StringBuilder class is definitely much faster than a string type. However if you just want to append something to a string a single time then a StringBuilder class is overkill. A simple string type variable in this case improves on resources use and readability of the C# source code.

Đơn giản chỉ cần chọn một cách chính xác giữa các đối tượng StringBuilder và các loại chuỗi, bạn có thể tối ưu hóa mã của bạn.

2. So sánh Non-Case-Sensitive Strings

Trong một ứng dụng đôi khi nó là cần thiết để so sánh hai biến chuỗi, bỏ qua các trường hợp. Phương pháp hấp dẫn và theo truyền thống là để chuyển đổi tất cả các chuỗi cho tất cả các trường hợp thấp hơn hoặc tất cả các trường hợp trên và sau đó so sánh chúng, giống như ví dụ:

str1.ToLower() == str2.ToLower()

Tuy nhiên nhiều lần gọi hàm ToLower() là một nút cổ chai trong performace. Bằng cách sử dụng hàm string.Compare() tích hợp sẵn, bạn có thể tăng tốc độ của các ứng dụng của mình.

Để kiểm tra xem hai chuỗi bằng nhau trường hợp bỏ qua sẽ trông như thế này:

string.Compare(str1, str2, true) == 0 //Ignoring cases

Chức năng C# string.Compare trả về một số nguyên đó là bằng 0 khi hai chuỗi đều bình đẳng.

3. Sử dụng string.Empty

này không phải là quá nhiều sự cải thiện hiệu suất vì nó là một sự cải thiện khả năng đọc, nhưng nó vẫn đếm như tối ưu hóa mã. Cố gắng thay thế các dòng như:

if (str == "")

với:

if (str == string.Empty)

Đây là thực hành lập trình đơn giản hơn và không có tác động tiêu cực đến hiệu suất.

Lưu ý, có một thực tế phổ biến rằng việc kiểm tra độ dài chuỗi là 0 nhanh hơn so sánh nó với chuỗi rỗng. Mặc dù điều đó có thể đúng sau khi nó không còn là cải tiến hiệu suất đáng kể nữa. Thay vào đó dính với string.Empty.

4. Thay thế ArrayList với Danh sách <>

ArrayList là hữu ích khi lưu trữ nhiều loại đối tượng trong cùng một danh sách. Tuy nhiên, nếu bạn đang giữ cùng một loại biến trong một ArrayList, bạn có thể tăng hiệu suất bằng cách sử dụng các đối tượng Danh sách <>.

Lấy ArrayList sau:

ArrayList intList = new ArrayList(); 
intList.add(10); 
return (int)intList[0] + 20; 

Thông báo nó chỉ chứa intergers. Sử dụng lớp List <> tốt hơn rất nhiều. Để chuyển nó sang một danh sách đánh máy, chỉ có các loại biến cần được thay đổi:

List<int> intList = new List<int>(); 

intList.add(10) 

return intList[0] + 20; 

Không cần để cast loại với Danh sách <>. Việc tăng hiệu suất có thể đặc biệt quan trọng với các kiểu dữ liệu nguyên thủy như số nguyên.

5. Sử dụng & & và || khai thác

Khi xây dựng nếu phát biểu, chỉ cần đảm bảo sử dụng đôi và ký hiệu (& &) và/hoặc kích đúp hoặc ký hiệu (||), (trong Visual Basic họ AndAlso và OrElse).

Nếu câu lệnh sử dụng & và | phải kiểm tra mọi phần của bản tuyên bố và sau đó áp dụng "và" hoặc "hoặc". Mặt khác, & & và || đi thourgh các báo cáo tại một thời điểm và dừng lại ngay sau khi điều kiện đã được đáp ứng hoặc không được đáp ứng.

Thực thi mã ít hơn luôn là một lợi ích performace nhưng nó cũng có thể tránh các lỗi thời gian chạy, hãy xem xét mã C# sau:

if (object1 != null && object1.runMethod()) 

Nếu object1 là null, với & & điều hành, object1.runMethod () sẽ không thực thi. Nếu toán tử & & được thay thế bằng &, object1.runMethod() sẽ chạy ngay cả khi object1 đã được biết là rỗng, gây ra ngoại lệ.

6. Thông minh try-catch

báo cáo Try-Catch có nghĩa là để bắt ngoại lệ mà nằm ngoài các lập trình viên điều khiển, chẳng hạn như kết nối với các trang web hoặc một thiết bị ví dụ. Sử dụng câu lệnh thử để giữ mã "đơn giản" thay vì sử dụng câu lệnh if để tránh các cuộc gọi dễ xảy ra lỗi khiến mã cực kỳ chậm hơn. Tái cơ cấu mã nguồn của bạn để yêu cầu các câu lệnh thử ít hơn.

7. Thay Phòng

C# là tương đối chậm khi nói đến hoạt động phân chia. Một giải pháp thay thế là thay thế các bộ phận bằng thao tác phép nhân để tối ưu hóa thêm C#.Bài viết giải thích chi tiết cách thực hiện chuyển đổi.

REFERENCE

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