Skip to main content

bash chậm tới mức nào?

trên những môi trường không có ngôn ngữ nào khác, bash vẫn là lựa chọn duy nhất:

  • docker entrypoint (script chạy 1 chương trình phức tạp trong docker)

bash không dùng để viết chương trình cần hiệu năng cao, nhưng liệu bash chậm tới mức nào?

Tính tổng từ 1 đến 1 triệu

#1
x=0
for i in {1..1000000} ; do
     x=$((x+i))
done
echo "$x"

#2
x=0
for i in $(seq 1 1000000) ; do
     x=$((x+i))
done
echo "$x"

#3
x=0
for ((i=1;i<=1000000;i++)); do
     x=$((x+i))
done
echo "$x"

#4
x=0
i=1
while [ $i -le 1000000 ]; do
    x=$((x+i))
    i=$((i+1))
done
echo "$x"

Trong 4 cách trên,

  • cách 1 với {1..1000000} tạo 1 triệu phần tử trong RAM (như Python dùng list(range(1,1_000_001))), dùng hết 284MB RAM.
  • cách 2 với seq 1 1000000 chỉ dùng 3.7MB RAM, nhưng phụ thuộc vào chương trình seq bên ngoài
  • cách 3 và 4 tương tự nhau nhưng cách 4 chạy trên tất cả cách loại (POSIX) shell.

Dùng shellcheck để biết cách 3 không chạy trên sh:

$ sudo apt install -y shellcheck
$ shellcheck --shell sh slow.sh

In slow.sh line 2:
for i in {1..1000000} ; do
         ^----------^ SC3009 (warning): In POSIX sh, brace expansion is undefined.


In slow.sh line 16:
for ((i=1;i<=1000000;i++)); do
^-^ SC3005 (warning): In POSIX sh, arithmetic for loops are undefined.
                      ^-- SC3018 (warning): In POSIX sh, ++ is undefined.

For more information:
  https://www.shellcheck.net/wiki/SC3005 -- In POSIX sh, arithmetic for loops...
  https://www.shellcheck.net/wiki/SC3009 -- In POSIX sh, brace expansion is u...
  https://www.shellcheck.net/wiki/SC3018 -- In POSIX sh, ++ is undefined.

Chạy cách 1 với {1..1000000}:

$ /usr/bin/time -v bash slow.sh
500000500000
    Command being timed: "bash slow.sh"
    User time (seconds): 2.14
    System time (seconds): 0.09
    Percent of CPU this job got: 99%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.24
...
    Maximum resident set size (kbytes): 284852
...
    Minor (reclaiming a frame) page faults: 72418
    Voluntary context switches: 1
    Involuntary context switches: 10
...

Chạy cách 4 với while:

$ /usr/bin/time -v bash slow.sh
500000500000    Command being timed: "bash slow.sh"
    User time (seconds): 5.05
    System time (seconds): 0.00
    Percent of CPU this job got: 99%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:05.05
...
    Maximum resident set size (kbytes): 3712
...
    Minor (reclaiming a frame) page faults: 155
    Voluntary context switches: 1
    Involuntary context switches: 27
...

Mất 5 giây để tính, trong khi với Python - 1 trong những ngôn ngữ lập trình chậm nhất, chỉ mất 0.08 giây tính cả thời gian bật Python, dùng 9MB RAM. Với Python 1 giây có thể tính tổng tới 15 triệu, tức bash chậm hơn Python 15*5 = 75 lần.

$ /usr/bin/time -v python3 sum.py
500000500000
    Command being timed: "python3 sum.py"
    User time (seconds): 0.08
    System time (seconds): 0.00
    Percent of CPU this job got: 100%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.08
...
    Maximum resident set size (kbytes): 9088
...
    Minor (reclaiming a frame) page faults: 943
    Voluntary context switches: 1
...

1 điều đáng chú ý là dùng dash - 1 POSIX shell có sẵn trên Ubuntu chạy nhanh hơn và tốn ít RAM hơn bash:

$ /usr/bin/time -v dash slow.sh
500000500000    Command being timed: "dash slow.sh"
    User time (seconds): 1.76
    System time (seconds): 0.00
    Percent of CPU this job got: 99%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.76
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 1536
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 78
    Voluntary context switches: 1
    Involuntary context switches: 45
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

Chậm thì sao?

Khi dùng để chạy các chương trình trong container, nếu không hoàn thành quá trình trong thời gian giới hạn, container sẽ bị restart để chạy lại từ đầu, và khi chạy lại thì vẫn chậm, vẫn không kịp, lại restart, ... tạo thành 1 vòng lặp vô hạn. Mặc dù ví dụ trên bash chạy 5 giây, nhưng khi dùng trong các container với 250m CPU (1/4 CPU), bash sẽ mất ~20 giây để chạy, trên thực tế, mất gần 50 giây:

$ systemd-run --scope --uid=1000 -p CPUQuota=25% /usr/bin/time -v bash slow.sh
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or other units.
Authenticating as: username
Password:
==== AUTHENTICATION COMPLETE ===
Running scope as unit: run-u139.scope
500000500000    Command being timed: "bash slow.sh"
    User time (seconds): 12.32
    System time (seconds): 0.00
    Percent of CPU this job got: 25%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:49.25
...
    Maximum resident set size (kbytes): 3712
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 152
    Voluntary context switches: 1
    Involuntary context switches: 623

Kết luận

bash chậm.

Written using

$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

Hết.

HVN at http://pymi.vn and https://www.familug.org.

Ủng hộ tác giả 🍺

Comments

Popular posts from this blog

Tài liệu và hướng dẫn học Python

Để tiết kiệm thời gian, tốt nhất là đi học PyMI Updated: 130617 Sau đây là các tài liệu khuyên dùng: Vì nhiều lý do, nên học python2.7 tại thời điểm hiện tại (giờ là tháng 6/2013 - muốn biết tại sao thì tự tìm hiểu) python 3.5+ (giờ là tháng 2/2017) Chuẩn bị: 1. biết bật tắt máy 2. biết cài python 3. tập gõ 10 ngón - gõ 2 ngón hay 1 ngón cũng không sao, nhưng 10 ngón là cách dễ nhất để gõ nhanh nhất. Tài liệu - Nên dùng tài liệu tại trang chủ của Python làm chính, tham khảo thêm các tài liệu khác tại http://www.familug.org/2016/12/free-ebook.html Căn bản, mới học 1.1 Python PyMI.vn https://pymi.vn/tutorial/ 1.2. Python offical tutorial kết hợp làm bài tập trên HackerRank  (đề bài bằng tiếng Anh, nhưng Google translate 1 lúc cũng ra vì có nhiều ví dụ mẫu đi kèm). Học viên của Pymi.vn có rất nhiều học viên đã tự học với Learn Python the hard way nhưng chưa thấy ai thành công cả. Hai link dưới nên đọc sau khi đã nắm được những phần cơ bản của ngôn ngữ pytho...

The PyMiers

New FAMILUG