Tôi có một khung kiểm tra nhỏ. Nó thực hiện một vòng lặp mà thực hiện như sau:Tăng tốc độ runhaskell
Tạo một tệp nguồn Haskell nhỏ.
Thực hiện việc này với
runhaskell
. Chương trình tạo ra các tệp đĩa khác nhau.Xử lý các tệp đĩa vừa tạo.
Điều này xảy ra vài chục lần. Nó chỉ ra rằng runhaskell
chiếm phần lớn thời gian thực hiện của chương trình.
Một mặt, thực tế là runhaskell
quản lý để tải tệp từ đĩa, mã hóa nó, phân tích cú pháp, phân tích phụ thuộc, tải thêm 20KB văn bản từ đĩa, tokenise và phân tích tất cả điều này, thực hiện suy luận kiểu đầy đủ, kiểm tra loại, desugar để Core, liên kết với mã máy biên dịch, và thực hiện điều trong một thông dịch viên, tất cả bên trong 2 giây của thời gian tường, thực sự là khá damned ấn tượng khi bạn nghĩ về nó. Mặt khác, tôi vẫn muốn làm cho nó đi nhanh hơn. ;-)
Biên dịch trình kiểm tra (chương trình chạy vòng lặp trên) đã tạo ra sự khác biệt nhỏ về hiệu suất. Biên dịch 20KB mã thư viện mà các tập lệnh liên kết chống lại việc tạo ra một cải tiến khá đáng chú ý hơn. Nhưng nó vẫn mất khoảng 1 giây cho mỗi yêu cầu của runhaskell
.
Tệp Haskell được tạo chỉ hơn 1KB mỗi tệp, nhưng chỉ một phần của tệp thực sự thay đổi. Có lẽ biên dịch tập tin và sử dụng chuyển đổi -e
của GHC sẽ nhanh hơn?
Ngoài ra, có thể đó là phí tổn liên tục tạo và phá hủy nhiều quá trình OS đang làm chậm quá trình này? Mọi lời gọi của runhaskell
có thể làm cho hệ điều hành khám phá đường dẫn tìm kiếm hệ thống, định vị tệp nhị phân cần thiết, tải nó vào bộ nhớ (chắc chắn điều này đã có trong bộ đệm đĩa?), Liên kết nó với bất kỳ tệp DLL nào và kích hoạt nó. Có cách nào tôi có thể (dễ dàng) giữ một ví dụ của GHC đang chạy, thay vì phải liên tục tạo và phá hủy quá trình hệ điều hành?
Cuối cùng, tôi cho rằng luôn có API GHC. Nhưng như tôi đã hiểu, điều đó thật khó khăn để sử dụng, rất không có giấy tờ, và dễ bị thay đổi triệt để ở mọi phát hành điểm nhỏ của GHC. Nhiệm vụ tôi đang cố gắng thực hiện chỉ rất đơn giản, vì vậy tôi không thực sự muốn mọi thứ trở nên phức tạp hơn mức cần thiết.
Đề xuất?
Cập nhật: Switching để GHC -e
(ví dụ, bây giờ tất cả mọi thứ được biên dịch, ngoại trừ các biểu hiện một được thực hiện) đã có sự khác biệt hiệu suất đo lường được. Nó có vẻ khá rõ ràng vào thời điểm này rằng đó là tất cả các chi phí hệ điều hành. Tôi tự hỏi liệu tôi có thể tạo một đường ống từ người thử nghiệm cho GHCi và do đó chỉ sử dụng một quy trình OS ...
Toàn bộ quy trình làm việc của bạn không nhìn chính xác theo mục tiêu hiệu suất, phải không? Tại sao bạn phải tạo mã Haskell? – leftaroundabout
Rõ ràng là bạn cần một daemon GHC! : p (một số người tôi biết sử dụng để nói đùa về việc tạo ra một daemon grep để tránh chi phí liên tục gọi grep trong khi khởi động, vv) – ivanm
+1 cho một nỗ lực hợp lý và được thực hiện tốt ở tối ưu hóa. – delnan