Giống như khi sử dụng SPECIALIZE
pragma và lợi ích hiệu suất của nó.
Bạn để trình biên dịch chuyên chức năng nếu bạn có hàm đa hình (loại lớp) và mong đợi nó được gọi thường xuyên tại một hoặc một vài trường hợp của lớp.
Chuyên môn loại bỏ tra cứu từ điển mà nó được sử dụng, và thường cho phép tối ưu hóa thêm, các chức năng thành viên của lớp thường có thể được gạch chân, và chúng phải chịu sự phân tích nghiêm ngặt. Nếu tối ưu hóa duy nhất có thể là loại bỏ tra cứu dicitonary, lợi ích sẽ không nói chung là rất lớn.
Tính đến GHC-7, nó có thể hữu ích hơn để cung cấp cho các chức năng một {-# INLINABLE #-}
pragma, mà làm (gần như không đổi, một số bình thường và desugaring được thực hiện) của nguồn có sẵn trong file giao diện, do đó chức năng có thể được chuyên và thậm chí có thể được trình bày tại trang cuộc gọi.
Nơi sử dụng RULES
. Tôi nghe mọi người nói về một quy tắc cụ thể không bắn? Làm thế nào để chúng ta kiểm tra điều đó?
Bạn có thể kiểm tra quy tắc nào đã kích hoạt bằng cách sử dụng tùy chọn dòng lệnh -ddump-rule-firings
. Điều đó thường đổ một số lượng lớn các quy tắc bị sa thải, vì vậy bạn phải tìm kiếm một chút cho các quy tắc của riêng bạn.
Bạn sử dụng quy tắc
khi bạn có một phiên bản hiệu quả hơn của một hàm với nhiều loại đặc biệt, ví dụ
{-# RULES
"realToFrac/Float->Double" realToFrac = float2Double
#-}
khi một số chức năng có thể được thay thế bằng phiên bản hiệu quả hơn cho các đối số đặc biệt, ví dụ:
{-# RULES
"^2/Int" forall x. x^(2 :: Int) = let u = x in u*u
"^3/Int" forall x. x^(3 :: Int) = let u = x in u*u*u
"^4/Int" forall x. x^(4 :: Int) = let u = x in u*u*u*u
"^5/Int" forall x. x^(5 :: Int) = let u = x in u*u*u*u*u
"^2/Integer" forall x. x^(2 :: Integer) = let u = x in u*u
"^3/Integer" forall x. x^(3 :: Integer) = let u = x in u*u*u
"^4/Integer" forall x. x^(4 :: Integer) = let u = x in u*u*u*u
"^5/Integer" forall x. x^(5 :: Integer) = let u = x in u*u*u*u*u
#-}
khi viết lại biểu thức theo luật chung có thể tạo mã tốt hơn để tối ưu hóa, ví dụ:
{-# RULES
"map/map" forall f g. (map f) . (map g) = map (f . g)
#-}
Sử dụng rộng rãi của RULES
theo phong cách thứ hai được thực hiện trong khuôn khổ hợp, ví dụ như trong thư viện text
, và cho các chức năng danh sách trong base
, một loại khác nhau của phản ứng tổng hợp (foldr/build
fusion) được thực hiện sử dụng các quy tắc.
Khi nào cần thực hiện đối số của hàm một cách nghiêm ngặt và khi nào điều đó sẽ hữu ích? Tôi hiểu rằng làm cho đối số chặt chẽ sẽ làm cho các đối số được đánh giá theo dạng bình thường, vậy tại sao tôi không nên thêm độ nghiêm ngặt vào tất cả các đối số hàm? Làm thế nào để tôi quyết định?
Đặt đối số một cách nghiêm ngặt sẽ đảm bảo rằng đối số được đánh giá là biểu mẫu chuẩn yếu đầu bình thường, không ở dạng bình thường.
Bạn không thực hiện tất cả các đối số một cách nghiêm ngặt vì một số hàm phải không nghiêm ngặt trong một số đối số của chúng để hoạt động và một số ít hiệu quả hơn nếu có trong tất cả các đối số.
Đối examplepartition
phải là không nghiêm ngặt trong số thứ hai của mình để làm việc ở tất cả vào danh sách vô hạn, tổng quát hơn mỗi chức năng được sử dụng trong foldr
phải là không nghiêm ngặt trong đối số thứ hai để làm việc trên danh sách vô hạn. Trên các danh sách hữu hạn, có hàm không nghiêm ngặt trong đối số thứ hai có thể làm cho nó hiệu quả hơn đáng kể (foldr (&&) True (False:replicate (10^9) True)
).
Bạn thực hiện một đối số nghiêm ngặt, nếu bạn biết rằng đối số phải được đánh giá trước khi bất kỳ công việc đáng giá nào có thể được thực hiện. Trong nhiều trường hợp, máy phân tích nghiêm ngặt của GHC có thể tự làm điều đó, nhưng tất nhiên là không phải tất cả.
Một trường hợp rất điển hình là ắc quy trong các vòng lặp hoặc đuôi, nơi thêm độ nghiêm ngặt ngăn cản việc xây dựng các khối lớn trên đường.
Tôi không biết quy tắc cứng nhắc và nhanh chóng về nơi cần thêm độ nghiêm ngặt, đối với tôi đó là vấn đề về trải nghiệm, sau một thời gian bạn tìm hiểu những địa điểm bổ sung tính nghiêm ngặt có thể giúp đỡ và nơi gây hại.
Theo quy tắc chung, việc lưu giữ dữ liệu nhỏ (như Int
) có ý nghĩa, nhưng có ngoại lệ.
Làm cách nào để xem và kiểm tra xem tôi có rò rỉ không gian trong chương trình của mình không? Các mẫu chung tạo thành rò rỉ không gian là gì?
Bước đầu tiên là sử dụng tùy chọn +RTS -s
(nếu chương trình được liên kết với rtsopts được bật). Điều đó cho bạn thấy có bao nhiêu bộ nhớ đã được sử dụng tổng thể, và bạn thường có thể đánh giá bằng cách đó cho dù bạn có một rò rỉ. Một đầu ra thông tin có thể thu được từ chạy chương trình với tùy chọn +RTS -hT
, tạo ra một hồ sơ heap có thể giúp xác định vị trí rò rỉ không gian (đồng thời, chương trình cần được liên kết với các rtsopts đã bật).
Nếu cần phân tích thêm, chương trình cần được biên dịch có bật hồ sơ (-rtsops -prof -fprof-auto
, trong GHC cũ, tùy chọn -fprof-auto
không có sẵn, tùy chọn -prof-auto-all
là thư gần nhất ở đó).
Sau đó, bạn chạy nó với các tùy chọn lược tả khác nhau và xem xét hồ sơ heap được tạo.
Hai nguyên nhân phổ biến nhất đối với rò rỉ không gian là
- quá nhiều sự lười biếng
- quá nhiều tính nghiêm minh
vị trí thứ ba có lẽ lấy bằng cách chia sẻ mong muốn, GHC không ít loại bỏ subexpression chung , nhưng đôi khi nó chia sẻ danh sách dài ngay cả khi không muốn.
Để tìm nguyên nhân rò rỉ, tôi biết lại không có quy tắc cứng và nhanh, và đôi khi, có thể khắc phục sự cố bằng cách thêm độ nghiêm ngặt ở một nơi hoặc bằng cách thêm sự lười biếng vào một nơi khác.
Làm cách nào để biết liệu có vấn đề gì với quá nhiều sự lười biếng? Tôi luôn có thể kiểm tra heap hồ sơ nhưng tôi muốn biết nguyên nhân chung, ví dụ và mô hình nơi lười biếng đau là gì?
Nói chung, sự lười biếng được mong muốn khi kết quả có thể được tăng lên và không mong muốn khi kết thúc quá trình xử lý hoàn tất, chẳng hạn như ở các nếp gấp bên trái hoặc thường có chức năng đệ quy đuôi.
RHW ch 25? http://book.realworldhaskell.org/read/profiling-and-optimization.html –
@DonStewart Cảm ơn .. Tôi đã đọc RWH .. Vấn đề là tôi biết họ làm gì nhưng tôi không có trực giác khi và nơi sử dụng của họ là quan trọng và không quan trọng. Tôi đã hỏi câu hỏi này để tìm hiểu các nguồn khác để nâng cao hơn nữa sự hiểu biết của tôi. – Satvik