2010-11-02 36 views
8

Tôi đang đọc Code Complete 2 và một trong những điểm được đề cập là tạo các chương trình con ngay cả đối với các thao tác dường như quá đơn giản để có các trình con riêng của chúng và cách có thể hữu ích.Làm cách nào để tôi có thể trực tiếp các chương trình con Perl?

Tôi biết tôi có thể inline functions in C and C++ sử dụng từ khóa inline. Nhưng tôi không bao giờ đi qua một cách để inline subroutines trong Perl.

Có cách nào để thông báo cho trình thông dịch Perl để nội tuyến các cuộc gọi chương trình con (hoặc tại sao không)?

+0

Bạn vẫn nên thực hiện theo lời khuyên ngay cả khi cơ hội cho nội tuyến có vẻ có vẻ hạn chế hơn trong Perl. –

Trả lời

21

Các chương trình con không đổi, tức là các chương trình con có mẫu thử rỗng và giá trị trả về không đổi, là nội dòng. Đó là cách số constant pragma xác định các hằng số:

sub five() { 5 } 

sẽ được gạch chân nếu nó được nhìn thấy trước lần sử dụng đầu tiên.

Nếu không, Perl cho phép chương trình con được định nghĩa lại động trong thời gian chạy, do đó nội tuyến không phù hợp.

Đối với các chương trình con luôn trả về cùng một giá trị cho cùng một yếu tố đầu vào, bạn có thể sử dụng memoization.

Chapter 13 of Programming Perl cung cấp một số thông tin về các bước tối ưu hóa được thực hiện bởi perl.

Điều này được gọi là xếp liên tục. Gấp liên tục không giới hạn trong các trường hợp đơn giản như chuyển 2 ** 10 thành 1024 vào thời gian biên dịch. Nó cũng giải quyết các cuộc gọi chức năng - cả các trình con con được xây dựng sẵn và được khai báo bởi người dùng, đáp ứng các tiêu chí từ phần "Nội tuyến các hàm liên tục" trong Chương 6, Chương trình con. Gợi nhớ kiến ​​thức khét tiếng về trình biên dịch của FORTRAN về các chức năng nội tại của riêng mình, Perl cũng biết được cái nào được xây dựng riêng để gọi trong quá trình biên dịch. Đó là lý do tại sao nếu bạn cố gắng ghi nhật ký 0.0 hoặc sqrt của hằng số âm, bạn sẽ phải chịu một lỗi biên dịch, không phải lỗi thời gian chạy và trình thông dịch không bao giờ chạy.

Xem thêm perldoc perlguts.

Bạn có thể thấy ảnh hưởng của không đổi gấp cho mình:

#!/usr/bin/perl 

use strict; use warnings; 

sub log_ok() { 1 } 

if (log_ok) { 
    warn "log ok\n"; 
} 
perl -MO=Deparse t.pl

Output:

sub log_ok() { 1 } 
use warnings; 
use strict 'refs'; 
do { 
    warn "log ok\n" 
}; 
t.pl syntax OK

Ở đây, gấp liên tục dẫn đến sự thay thế của khối if với một khối do vì trình biên dịch biết rằng log_ok sẽ luôn trả về giá trị thực. Mặt khác, với:

#!/usr/bin/perl 

use strict; use warnings; 

sub log_ok() { 0.5 > rand } 

if (log_ok) { 
    warn "log ok\n"; 
} 

đầu ra Deparse:

sub log_ok() { 
    use warnings; 
    use strict 'refs'; 
    0.5 > rand; 
} 
use warnings; 
use strict 'refs'; 
if (log_ok) { 
    warn "log ok\n"; 
} 
t.pl syntax OK

Một trình biên dịch C có thể đã thay thế if (log_ok) với if (0.5 > rand). perl không làm điều đó.

5

Perl chỉ cho phép các hàm liên tục nội dòng.Từ perldoc perlsub:

Các chức năng với mẫu thử() là các ứng cử viên tiềm năng cho nội tuyến. Nếu kết quả sau khi tối ưu hóa và gấp liên tục là một trong hai hằng số hoặc vô hướng lexically-scoped trong đó có không tài liệu tham khảo khác, sau đó nó sẽ được sử dụng thay cho các cuộc gọi chức năng làm mà không &.

3

Tôi đã không cố gắng nào trong số này, nhưng nếu bạn có thời gian, bạn có thể thử

  1. Macro
  2. macro
  3. hoặc thậm chí Filter::Macro

Họ' lại tất cả các bộ lọc nguồn, do đó bạn sẽ phải kiểm tra lợi tức đầu tư của mình trong hiệu suất. Thực tế cuối cùng có đánh giá trên cpanratings. (Bỏ qua nỗ lực Dan Dascalescu để điều chỉnh các module Perl "không phận".)

-Trên thực tế, cuối cùng một Filter::Macro sử dụng Filter::Simple::Compile (mà lần lượt sử dụng Module::Compile) để biên dịch các thói quen, vì vậy này có thể thực hiện trên các phương pháp lọc nguồn khác. Nhưng áp dụng standard caveats on source filters.

1

Tốc độ có lẽ không nên cân nhắc khi viết Perl. Đi trước và làm cho mọi thứ hoạt động. Nếu hồ sơ sau này cho thấy rằng bạn đang dành rất nhiều thời gian trong một chức năng đơn giản do gọi nó rất nhiều, sau đó nội tuyến có chức năng chính mình.

+0

;) Tối ưu hóa sớm là gốc rễ của mọi điều ác - Donald E. Knuth nói, và đúng như vậy. – Jinxed

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