ฉันแค่จะให้คำแนะนำทั่วไปในคำตอบนี้ไม่ใช่มาตรฐาน การวัดประสิทธิภาพเป็นวิธีเดียวที่จะตอบคำถามเกี่ยวกับประสิทธิภาพได้อย่างน่าเชื่อถือ แต่เนื่องจากคุณไม่ได้บอกว่าคุณมีการจัดการข้อมูลมากน้อยเพียงใดและคุณใช้งานการดำเนินการนี้บ่อยแค่ไหนจึงไม่มีทางทำเกณฑ์มาตรฐานที่มีประโยชน์ได้ มีประสิทธิภาพมากขึ้นสำหรับ 10 รายการและอะไรที่มีประสิทธิภาพมากกว่าสำหรับ 1000000 รายการมักไม่เหมือนกัน
ตามกฎทั่วไปของหัวแม่มือการเรียกใช้คำสั่งภายนอกนั้นมีราคาแพงกว่าการทำอะไรบางอย่างกับการสร้างเชลล์บริสุทธิ์ตราบใดที่รหัสเชลล์บริสุทธิ์ไม่เกี่ยวข้องกับการวนซ้ำ ในทางกลับกัน shell loop ที่วนซ้ำสตริงขนาดใหญ่หรือสตริงจำนวนมากมีแนวโน้มที่จะช้ากว่าการเรียกใช้หนึ่งของเครื่องมือพิเศษ ตัวอย่างเช่นการวนลูปของคุณcut
อาจสังเกตได้ช้าในทางปฏิบัติ แต่ถ้าคุณพบวิธีที่จะทำสิ่งทั้งหมดด้วยการcut
เรียกใช้ครั้งเดียวที่น่าจะเร็วกว่าการทำสิ่งเดียวกันกับการจัดการสตริงในเชลล์
โปรดทราบว่าจุดตัดสามารถแตกต่างกันมากระหว่างระบบ ขึ้นอยู่กับเคอร์เนลว่ามีการกำหนดค่าตัวกำหนดตารางเวลาของเคอร์เนลอย่างไรในระบบไฟล์ที่มีโปรแกรมเรียกทำงานภายนอกขึ้นอยู่กับความกดดันของซีพียูและหน่วยความจำที่มีอยู่ในขณะนี้และปัจจัยอื่น ๆ อีกมากมาย
อย่าโทรexpr
ไปหาเลขคณิตหากคุณกังวลเกี่ยวกับประสิทธิภาพ ที่จริงแล้วอย่าโทรexpr
ไปทำการคำนวณทางคณิตศาสตร์เลย expr
เปลือกหอยได้ในตัวในการคำนวณซึ่งเป็นที่ชัดเจนและเร็วกว่าการกล่าวอ้าง
คุณดูเหมือนจะใช้ bash เนื่องจากคุณใช้ bash constructs ที่ไม่มีอยู่ใน sh แล้วทำไมคุณไม่ใช้อาเรย์ล่ะ? อาเรย์เป็นวิธีแก้ปัญหาที่เป็นธรรมชาติที่สุดและมีแนวโน้มว่าจะเร็วที่สุด โปรดสังเกตว่าดัชนีอาร์เรย์เริ่มต้นที่ 0
list=(1 2 3 5 9 8 6 90 84 9 3 2 15 75 55)
for ((count = 0; count += 3; count < ${#list[@]})); do
echo "${list[$count]}"
done
สคริปต์ของคุณอาจเร็วขึ้นหากคุณใช้ sh หากระบบของคุณมีเส้นประหรือ ksh sh
แทนที่จะเป็นทุบตี หากคุณใช้ sh คุณจะไม่ได้รับอาร์เรย์ที่มีชื่อ แต่คุณยังคงได้รับอาร์เรย์หนึ่งในพารามิเตอร์ตำแหน่งซึ่งคุณสามารถตั้งค่าset
ได้ ในการเข้าถึงองค์ประกอบที่ตำแหน่งที่ไม่รู้จักจนกระทั่งถึงรันไทม์คุณจะต้องใช้eval
(ดูแลสิ่งต่าง ๆ อย่างถูกต้อง!)
# List elements must not contain whitespace or ?*\[
list='1 2 3 5 9 8 6 90 84 9 3 2 15 75 55'
set $list
count=1
while [ $count -le $# ]; do
eval "value=\${$count}"
echo "$value"
count=$((count+1))
done
หากคุณต้องการเข้าถึงอาร์เรย์เพียงครั้งเดียวและไปจากซ้ายไปขวา (ข้ามค่าบางค่า) คุณสามารถใช้shift
แทนดัชนีตัวแปรได้
# List elements must not contain whitespace or ?*\[
list='1 2 3 5 9 8 6 90 84 9 3 2 15 75 55'
set $list
while [ $# -ge 1 ]; do
echo "$1"
shift && shift && shift
done
วิธีการใดที่เร็วกว่านั้นขึ้นอยู่กับเชลล์และจำนวนองค์ประกอบ
ความเป็นไปได้อีกอย่างหนึ่งคือการใช้การประมวลผลสตริง มันมีข้อดีของการไม่ใช้พารามิเตอร์ตำแหน่งดังนั้นคุณสามารถใช้มันเพื่อสิ่งอื่นได้ มันจะช้ากว่าสำหรับข้อมูลจำนวนมาก แต่ไม่น่าจะสร้างความแตกต่างที่เห็นได้ชัดเจนสำหรับข้อมูลจำนวนเล็กน้อย
# List elements must be separated by a single space (not arbitrary whitespace)
list='1 2 3 5 9 8 6 90 84 9 3 2 15 75 55'
while [ -n "$list" ]; do
echo "${list% *}"
case "$list" in *\ *\ *\ *) :;; *) break;; esac
list="${list#* * * }"
done