2011-12-04 32 views
6

Làm thế nào để bạn bắt buộc đánh giá đầu vào của hàm trước khi đánh giá hàm trong Criterion? Tôi đang cố gắng để chuẩn một số chức năng, nhưng sẽ muốn loại trừ thời gian để đánh giá thunk đầu vào. Mã được đề cập sử dụng unboxed vectors cho đầu vào, không thể sâu được cho các vectơ Int. Ví dụ đoạn mã dưới đây:Bắt buộc đánh giá đầu vào chức năng trước khi đo điểm chuẩn trong tiêu chí

-- V is Data.Vector.Unboxed 
shortv = V.fromList [1..10] :: V.Vector GHC.Int.Int16 
intv = V.fromList [1..10] :: V.Vector GHC.Int.Int32 

main :: IO() 
main = defaultMain [ 
      bench "encode ShortV" $ whnf encodeInt16V shortv 
      ,bench "encode IntV" $ whnf encodeInt32V intv 
     ] 

Tiêu chí chuẩn bao gồm thời gian để xây dựng shortv, và intv đầu vào khi điểm chuẩn trên các chức năng. Các phép đo tiêu chuẩn là dưới đây - nó đo khoảng ~ 400ns cho mỗi chức năng mà dường như bao gồm thời gian xây dựng cho các đầu vào cũng như:

benchmarking encode ShortV 
mean: 379.6917 ns, lb 378.0229 ns, ub 382.4529 ns, ci 0.950 
std dev: 10.79084 ns, lb 7.360444 ns, ub 15.89614 ns, ci 0.950 

benchmarking encode IntV 
mean: 392.2736 ns, lb 391.2816 ns, ub 393.4853 ns, ci 0.950 
std dev: 5.565134 ns, lb 4.694539 ns, ub 6.689224 ns, ci 0.950 

Bây giờ, nếu phần chính benchmark mã của được sửa đổi xuống dưới (bằng cách loại bỏ chức năng ghế thứ hai) :

main = defaultMain [ 
      bench "encode ShortV" $ whnf encodeInt16V shortv 
     ] 

shortv đầu vào dường như được đánh giá trước encodeInt16V hàm được quy chuẩn hóa. Đó là đầu ra mong muốn thực sự cho tôi vì điểm chuẩn này đo thời gian thực hiện hàm, không kể thời gian để xây dựng đầu vào. Tiêu chí đầu ra bên dưới:

benchmarking encode ShortV 
mean: 148.8488 ns, lb 148.4714 ns, ub 149.6279 ns, ci 0.950 
std dev: 2.658834 ns, lb 1.621119 ns, ub 5.184792 ns, ci 0.950 

Tương tự, nếu tôi chỉ đạt chuẩn "mã hóa IntV", tôi cũng nhận được ~ 150ns thời gian cho điểm chuẩn đó.

Tôi biết từ tài liệu Tiêu chí rằng nó cố gắng tránh đánh giá lười biếng để có điểm chuẩn chính xác hơn. Nó có ý nghĩa, và không thực sự là một vấn đề ở đây. Câu hỏi của tôi là làm thế nào để xây dựng các đầu vào shortv và intv để chúng đã được đánh giá trước khi được chuyển đến chức năng băng ghế dự bị. Ngay bây giờ, tôi có thể thực hiện điều này bằng cách hạn chế defaultMain để chỉ chuẩn một hàm tại một thời điểm (như tôi đã chỉ ra ở trên), nhưng đó không phải là một giải pháp lý tưởng.

EDIT1

Có cái gì khác xảy ra ở đây với tiêu chí chuẩn mực, và nó dường như chỉ xảy ra trên mảng Vector, không danh sách. Nếu tôi buộc đánh giá đầy đủ bằng cách in shortv và intv, điểm chuẩn vẫn đo thời gian là ~ 400ns, không ~ 150ns. Mã cập nhật dưới đây:

main = do 
    V.forM_ shortv $ \x -> do print x 
    V.forM_ intv $ \x -> do print x 
    defaultMain [ 
      bench "encode ShortV" $ whnf encodeInt16V shortv 
      ,bench "encode IntV" $ whnf encodeInt32V intv 
     ] 

đầu ra tiêu chí (còn, có 158,4% giá trị ngoại biên mà có vẻ không chính xác):

estimating clock resolution... 
mean is 5.121819 us (160001 iterations) 
found 253488 outliers among 159999 samples (158.4%) 
    126544 (79.1%) low severe 
    126944 (79.3%) high severe 
estimating cost of a clock call... 
mean is 47.45021 ns (35 iterations) 
found 5 outliers among 35 samples (14.3%) 
    2 (5.7%) high mild 
    3 (8.6%) high severe 

benchmarking encode ShortV 
mean: 382.1599 ns, lb 381.3501 ns, ub 383.0841 ns, ci 0.950 
std dev: 4.409181 ns, lb 3.828800 ns, ub 5.216401 ns, ci 0.950 

benchmarking encode IntV 
mean: 394.0517 ns, lb 392.4718 ns, ub 396.7014 ns, ci 0.950 
std dev: 10.20773 ns, lb 7.101707 ns, ub 17.53715 ns, ci 0.950 

Trả lời

3

Bạn có thể sử dụng trước khi gọi evaluate defaultMain để chạy các điểm chuẩn. Không chắc chắn nếu nó là giải pháp sạch nhất, nhưng nó sẽ trông như thế này:

main = do 
    evaluate shortv 
    evaluate intv 
    defaultMain [..] 
+0

Thử nghiệm với đánh giá, như bạn đã đề xuất, nhưng nó không thay đổi kết quả. Tôi đoán điều này là bởi vì nó đánh giá các biểu thức để whnf, không nf. – Sal

+2

Tôi không nghĩ rằng đây có thể là vấn đề: một 'Vector' trên ví dụ: 'Int32' là một kiểu mới xung quanh một' Data.Vector.Primitive.Vector Int32', chỉ chứa các trường 'Int' và 'ByteArray'. Cái cuối cùng là một kiểu dữ liệu xung quanh một 'ByteArray #' nguyên thủy, mà tôi nghĩ là nghiêm ngặt. Tuy nhiên, việc thử nghiệm phải đơn giản: chỉ cần thay đổi cuộc gọi 'evaluation' thành một cái gì đó để in tổng số thay vào đó. –

+0

Có, bạn đã đúng. Tôi đã thử forM_ với lệnh in trên mảng vectơ và nhận được kết quả tương tự.Có một cái gì đó khác đang xảy ra, và nó có vẻ rất cụ thể cho mảng Vector. Tôi không thấy vấn đề này khi tôi viết các hàm ban đầu với các danh sách. – Sal

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