2010-04-24 35 views
6

Tôi đã viết nhiều tập lệnh trong Perl và shell và tôi đã so sánh thời gian thực thi thực tế. Trong tất cả các trường hợp, kịch bản Perl nhanh hơn 10 lần so với kịch bản lệnh shell.Có thể viết kịch bản lệnh shell nhanh hơn tập lệnh tương đương trong Perl không?

Vì vậy, tôi tự hỏi liệu có thể viết một kịch bản lệnh shell nhanh hơn cùng một tập lệnh trong Perl không? Và tại sao Perl nhanh hơn shell mặc dù tôi sử dụng hàm system trong kịch bản Perl?

+1

Tôi không biết. Nhưng nó có thể phụ thuộc vào kịch bản. đăng một ví dụ kịch bản là một điều tốt. cũng không có chức năng hệ thống 100% trong perl có thể là thư viện C. – xenoterracide

+0

Bạn có yêu cầu một ví dụ về kịch bản lệnh shell nhanh hơn tập lệnh Perl tương ứng không? Hoặc, đối với mỗi tập lệnh Perl (ít nhất, mỗi tập lệnh Perl của một biểu mẫu cụ thể), nếu có thể viết một kịch bản lệnh shell tương đương, nhanh hơn? – outis

+0

ví dụ về kịch bản lệnh shell nhanh hơn tập lệnh Perl tương ứng :) – JohnJohnGa

Trả lời

6

Có vài cách để làm cho trình bao của bạn (ví dụ: Bash) thực thi nhanh hơn.

  1. Cố gắng sử dụng ít lệnh bên ngoài hơn nếu nội bộ của Bash có thể thực hiện tác vụ cho bạn. Ví dụ: sử dụng quá mức sed, grep, awk et cho chuỗi/văn bản thao tác.
  2. Nếu bạn đang thao tác các tệp tương đối lớn, không sử dụng bash trong khi đọc vòng lặp. Sử dụng awk. Nếu bạn đang thao tác các tệp BIG thực sự, bạn có thể sử dụng grep để tìm kiếm các mẫu bạn muốn và sau đó chuyển chúng thành awk để "chỉnh sửa".Thuật toán tìm kiếm của grep rất tốt và nhanh. Nếu bạn muốn nhận được chỉ phía trước hoặc kết thúc của tập tin, sử dụng đầu và đuôi.
  3. các công cụ thao tác tệp như sed, cut, grep, wc, v.v. tất cả có thể được thực hiện với một tập lệnh awk hoặc sử dụng nội bộ Bash nếu không phức tạp. Do đó, bạn có thể cố gắng cắt giảm việc sử dụng các công cụ này chồng lên nhau trong các chức năng của chúng. Các đường ống/chuỗi Unix là tuyệt vời, nhưng sử dụng quá nhiều đường dẫn, ví dụ: command|grep|grep|cut|sed làm cho mã của bạn chậm. Mỗi ống là một chi phí. Đối với ví dụ này, chỉ một awk làm tất cả. command | awk '{do everything here}' Công cụ gần nhất mà bạn có thể sử dụng có thể phù hợp với tốc độ của Perl đối với một số tác vụ nhất định, ví dụ như thao tác chuỗi hoặc toán học, thật là lúng túng. Đây là điểm chuẩn thú vị cho this solution. Có khoảng 9million số trong file

Output

$ head -5 file 
1 
2 
3 
34 
42 
$ wc -l <file 
8999987 

# time perl -nle '$sum += $_ } END { print $sum' file 
290980117 

real 0m13.532s 
user 0m11.454s 
sys  0m0.624s 

$ time awk '{ sum += $1 } END { print sum }' file 
290980117 

real 0m9.271s 
user 0m7.754s 
sys  0m0.415s 

$ time perl -nle '$sum += $_ } END { print $sum' file 
290980117 

real 0m13.158s 
user 0m11.537s 
sys  0m0.586s 

$ time awk '{ sum += $1 } END { print sum }' file 
290980117 

real 0m9.028s 
user 0m7.627s 
sys  0m0.414s 

Đối với mỗi thử, awk là nhanh hơn so với Perl.

Cuối cùng, cố gắng tìm hiểu awk vượt ra ngoài những gì họ có thể làm như một lớp lót.

+0

Cảm ơn! đó chính xác là những gì tôi đang tìm kiếm! – JohnJohnGa

1

Không, tôi nghĩ rằng đó là bất khả thi:
lệnh bash thực sự là ngôn ngữ interpeted, nhưng chương trình Perl được biên dịch để bytecode trước khi thực hiện

+1

Ok - vậy tại sao mọi người sử dụng Shell script? bởi vì họ không biết perl? :) – JohnJohnGa

+1

Bởi vì nó là tự nhiên để sử dụng lệnh shell để thực hiện lệnh :) –

+4

@JohnJohnGa: Bởi vì người-thời gian là có giá trị hơn CPU-thời gian. Nếu mất hơn 5 phút để viết một phiên bản Perl sẽ tiết kiệm được vài giây cho mỗi lần chạy, thì bash có lẽ là lựa chọn tốt hơn. Cá nhân, tôi là một fan hâm mộ lớn của Perl, nhưng, khi tôi sẽ tự động hóa một loạt các lệnh mà không cần điều khiển luồng, tôi sẽ vẫn làm điều đó với bash thay vào đó. –

-2

Yes. Mã C sẽ nhanh hơn mã Perl cho cùng một thứ, do đó, một tập lệnh sử dụng một tệp thực thi được biên dịch để thực hiện nhiều công việc sẽ nhanh hơn một chương trình perl làm điều tương tự.

Tất nhiên, chương trình Perl có thể được viết lại để sử dụng tệp thực thi, trong trường hợp này có thể sẽ nhanh hơn một lần nữa.

+0

Điều đó có thể đúng trong một số trường hợp, nhưng hãy nhớ rằng Perl là mã C. Tùy thuộc vào công việc, bạn có thể không thể đánh bại cơ sở hạ tầng C được tối ưu hóa cao của Perl. –

4

này có thể rơi một cách nguy hiểm gần cánh tay chủ tịch tối ưu hóa, nhưng đây là một số ý kiến ​​cho rằng có thể hợp lý hóa kết quả của bạn:

  • Fork/exec: hầu hết mọi thứ hữu ích mà được thực hiện bằng một kịch bản shell được thực hiện thông qua một shell-out, đó là bắt đầu một shell mới và chạy một lệnh như sed, awk, cat vv. Thường thì không, sau đó một quá trình được thực hiện và dữ liệu được di chuyển qua đường ống.

  • Cấu trúc dữ liệu: Cấu trúc dữ liệu của Perl phức tạp hơn sau đó là của Bash hoặc Csh. Điều này thường buộc các lập trình viên được tạo ra với lưu trữ dữ liệu. Điều này có thể gồm các hình thức của:

    • sử dụng phi cấu trúc dữ liệu tối ưu (mảng thay vì băm) dữ liệu
    • cửa hàng ở dạng văn bản (ví dụ số nguyên như dây đàn) mà cần phải được giải thích lại mỗi lần.
    • lưu dữ liệu vào một tệp và phân tích lại nó một lần nữa.
    • , vv
  • không được tối ưu hóa thực hiện: một số cấu trúc vỏ có thể không được thiết kế với tối ưu hóa trong tâm trí, nhưng với người sử dụng thuận tiện. Ví dụ, tôi có lý do để tin rằng việc thực hiện bash của việc mở rộng tham số đặc biệt là ${foo//search/replace} là phụ tối ưu tương đối so với hoạt động tương tự trong sed. Điều này thường không phải là vấn đề đối với các công việc hàng ngày.

1

Một số lệnh shell nhất định có thể chạy nhanh hơn Perl, trong một số trường hợp. Tôi từng điểm chuẩn một kịch bản sed đơn giản chống lại tương đương trong perl, và sed thắng. Nhưng khi các yêu cầu trở nên phức tạp hơn, phiên bản perl bắt đầu đánh bại phiên bản sed. Vì vậy, câu trả lời là, nó phụ thuộc. Nhưng vì những lý do khác, (đơn giản, bảo trì, vv) tôi muốn dựa vào việc làm mọi thứ trong Perl, trừ khi các yêu cầu rất đơn giản, và tôi mong đợi họ ở lại như vậy.

2

Được rồi, tôi biết tôi đang yêu cầu bằng cách mở một hộp giun khép kín cách đây hai năm, nhưng tôi không hài lòng 100% với bất kỳ câu trả lời nào.

Câu trả lời đúng là CÓ. Nhưng hầu hết các lập trình viên mới sẽ vẫn truy cập Perl và Python và viết mã để đấu tranh mạnh mẽ để GỌI CALLS thành EXECUTABLES bên ngoài vì họ thiếu sự cố vấn hoặc kinh nghiệm cần biết khi sử dụng công cụ nào.

Korn Shell (ksh) có toán học dựng sẵn nhanh, và động cơ regex hoàn toàn có khả năng và nhanh chóng, thở hổn hển, có thể xử lý loại regex Perl. Nó cũng có mảng kết hợp. Nó thậm chí có thể tải thư viện .so bên ngoài. Và đó là một sản phẩm hoàn thiện và trưởng thành cách đây 10 năm. Nó thậm chí đã được cài đặt trên máy Mac của bạn.

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