2011-11-21 25 views
5

Tôi có một chức năng rất đơn giản trong ứng dụng của tôi rằng hiện rất nhiều công việc và chiếm thời gian tính toán nhất:Tốc độ lên Data.Array khai thác hàng và lọc

f :: Int -> Array (Int,Int) Int -> [Int] 
f x arr = [v | v <- range (l,u), vv <- [g!(x,v)], vv /= 0] 
      where ((_,l), (_,u)) = bounds arr 

Điều này không là: trích xuất một hàng tại chỉ số x từ mảng arr và trả về tất cả các chỉ mục cột có các thành phần \= 0. Vì vậy, ví dụ, với ma trận sau đây với giới hạn ((0,0),(2,2)):

arr = [[0, 0, 5], 
     [4, 0, 3], 
     [0, 3, 1]] -- for simplicity in [[a]] notation 

sản lượng dự kiến ​​là

f 0 arr == [2] 
f 1 arr == [0,2] 
f 2 arr == [1,2] 

Làm thế nào để tăng tốc độ f và hồ sơ với chi tiết hơn những gì thực sự mất phần lớn thời gian tính toán trong f (danh sách xây dựng, truy cập mảng, vv)?

Cảm ơn bạn!

Trả lời

2
f x arr = [v | v <- range (l,u), vv <- [g!(x,v)], vv /= 0] 

Tôi cho rằng g là một lỗi đánh máy, nó phải là arr.
Thay vì range (l,u) sử dụng [l .. u], trình biên dịch có thể tối ưu hóa trước cũng như sau, nhưng [l .. u] là thành ngữ hơn (và có thể trình biên dịch không thể tối ưu hóa trước đây).
Đừng tạo ra một danh sách một yếu tố vô nghĩa, bạn có thể sử dụng các bài kiểm tra trực tiếp,

f x arr = [v | v <- [l .. u], arr!(x,v) /= 0] 

Trình biên dịch có thể một lần nữa có thể viết lại cựu để sau này, nhưng a) sau này là rõ ràng hơn nhiều, và b) không có nguy cơ trình biên dịch không thể.

Để tìm ra nơi mà thời gian rảnh, bạn có thể chèn chú thích chi phí trung tâm,

f x arr = [v | v <- {-# SCC "Range" #-} [l .. u], {-# SCC "ZeroTest" #-} (arr!(x,v) /= 0)] 

nhưng chú thích như vô hiệu hóa nhiều optimisations (biên soạn cho hồ sơ luôn luôn làm), do đó hình ảnh bạn nhận được từ hồ sơ có thể sai lệch và khác với những gì thực sự xảy ra trong chương trình được tối ưu hóa.

+0

Tôi vừa kiểm tra nguồn thư viện và 'dải ô' phải giống với' [..] '. – sclv

+0

@sclv Vâng, nó giống nhau. Tuy nhiên đó là một lớp thêm trình biên dịch phải bóc vỏ. Nếu không có vấn đề gì với 'Int', nhưng có thể là do các loại khác. –

+0

Cảm ơn bạn đã bình luận của bạn. Điều này thực sự đã giúp khá nhiều và tôi nghĩ rằng vấn đề là việc xây dựng danh sách. Những gì tôi thực sự cần cuối cùng là một lần trong danh sách, vì vậy nó có thể là tốt hơn để làm gấp trên mảng trực tiếp trong người gọi. – bbtrb

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