Tôi đã đánh giá hiệu suất của một framework mà tôi đang viết trong Perl và tôi nhận được yêu cầu giảm 50% mỗi giây so với codebase hiện tại của chúng tôi (một số lần truy cập là dễ hiểu, vì chúng tôi đang đi từ mã spaghetti theo thủ tục sang khung công tác OOP MVC).Làm cách nào để tôi có thể thực thi mã không hiệu quả chỉ khi biên dịch khi sử dụng mod_perl?
Ứng dụng đang chạy dưới mod_perl và tôi đã thêm Moose và tất cả mã khung của tôi vào số startup.pl script, tự tăng gấp đôi yêu cầu của tôi trên mỗi giây. Tôi đang tìm cách nâng cao hơn nữa con số này để có được nó càng gần càng tốt với số tiền hiện có. Lập luận là ở đây rằng đây là tối ưu hóa sớm, nhưng có một vài sự thiếu hiệu quả rõ ràng mà tôi muốn sửa chữa và xem nó ảnh hưởng như thế nào đến hiệu suất.
Giống như hầu hết các khung công tác, tôi có tệp cấu hình và người điều phối. Phần cấu hình được xử lý bởi Config::General, do đó, một chút IO và phân tích cú pháp có liên quan để tải tệp cấu hình của tôi vào ứng dụng. Vấn đề lớn nhất tôi thấy ở đây là tôi đang làm điều này cho MỌI YÊU CẦU mà đến!
Chạy Devel :: Dprof trên ứng dụng của tôi trỏ tới Config :: General :: BEGIN và một loạt các mô-đun IO có liên quan là một trong những điểm chậm chính không phải là Moose. Vì vậy, những gì tôi muốn làm, và những gì làm cho nhiều ý nghĩa hơn trong hindsight là tận dụng lợi thế của sự kiên trì mod_perl và các công cụ biên dịch startup.pl chỉ làm công việc để tải trong tập tin cấu hình một lần - khi máy chủ bắt đầu.
Vấn đề là tôi không quá quen thuộc với cách làm việc này.
Hiện nay mỗi dự án có một lớp bootstrapping PerlHandler mà là khá nạc và trông như thế này:
use MyApp;
MyApp->new(config_file => '/path/to/site.config')->run();
MyApp.pm thừa hưởng từ các module Project khuôn khổ, trong đó có mã này:
my $config = Config::General->new(
-ConfigFile => $self->config_file,
-InterPolateVars => 1,
);
$self->config({$config->getall});
Để chỉ làm điều này vào thời gian biên dịch, cả hai mô đun cơ sở dự án và bootstrap của tôi sẽ phải thay đổi (tôi nghĩ), nhưng tôi không chắc chắn về những thay đổi để thực hiện và vẫn giữ mã đẹp và gọn gàng. Có ai có thể chỉ cho tôi đi đúng hướng không?
CẬP NHẬT
Tôi đã thử các BEGIN BLOCK trong mỗi phương pháp mô-đun dự án như mô tả của ysth trong câu trả lời của mình. Vì vậy, tôi bây giờ có:
package MyApp::bootstrap;
use MyApp;
my $config;
BEGIN
{
$config = {Config::General->new(...)->getall};
}
sub handler { ..etc.
MyApp->new(config => $config)->run();
thay đổi nhanh chóng này mình đã cho tôi một tăng 50% yêu cầu mỗi giây, xác nhận suy nghĩ của tôi rằng tập tin cấu hình là một nút cổ chai giá trị sửa chữa lớn. Con số chuẩn trên máy dev cũ của chúng tôi là 60rps và khung của tôi đã tăng từ 30rps lên 45rps với sự thay đổi này một mình. Đối với những người nói Moose là chậm và có một thời gian biên dịch hit .. Tôi đã tăng cùng (50%) khi biên dịch tất cả các mã Moose của tôi lúc khởi động như tôi đã làm trước khi biên dịch tập tin cấu hình của tôi.
Vấn đề duy nhất tôi có bây giờ là vi phạm nguyên tắc DRY vì cùng một Config :: General-> mã mới nằm trong mọi khối BEGIN chỉ với đường dẫn đến tệp cấu hình khác nhau. Tôi có một vài chiến lược khác nhau để hạn chế điều này, nhưng tôi chỉ muốn đăng kết quả của sự thay đổi này.
Vấn đề với giải pháp này là bạn phải tạo khối BEGIN này với mã đó cho mọi mô-đun dự án (mỗi dự án có tệp cấu hình riêng). Tôi đã thực hiện điều này một cách nhanh chóng và tôi nhận được yêu cầu tăng thêm 50% mỗi giây, vì vậy, tôi vẫn trả lời câu trả lời, bởi vì nó trả lời câu hỏi của tôi –
Để xem "mỗi dự án cần cấu hình riêng", bạn có thể 1) Kết hợp tất cả các tệp thành 1 với các phần khác nhau (có thể sử dụng tệp INI hoặc hoặc Config :: ApacheFormat). 2) có một lớp cấu hình giữ mỗi tập tin cấu hình trong một băm và kéo một trong những quyền dựa trên một số $ ENV var. – mpeters
Tôi chưa bao giờ nghĩ đến việc có một tệp cấu hình khổng lồ vì nó sẽ bảo trì như thế nào khi bạn có hàng trăm dự án ... nhưng thực sự có rất nhiều lợi ích khi thực hiện các kết nối cơ sở dữ liệu trên tất cả các dự án trong một số ít trường hợp. Cảm ơn. –