Darò solo alcuni consigli generali in questa risposta, e non benchmark. I benchmark sono l'unico modo per rispondere in modo affidabile alle domande sulle prestazioni. Ma dal momento che non dici quanti dati stai manipolando e quanto spesso esegui questa operazione, non c'è modo di fare un benchmark utile. Ciò che è più efficiente per 10 articoli e ciò che è più efficiente per 1000000 articoli spesso non è lo stesso.
Come regola generale, invocare comandi esterni è più costoso che fare qualcosa con costrutti di pura shell, purché il codice di pura shell non implichi un ciclo. D'altra parte, un ciclo di shell che scorre su una stringa di grandi dimensioni o una grande quantità di stringa è probabilmente più lento di una chiamata di uno strumento per scopi speciali. Ad esempio, l'invocazione del tuo ciclo cut
potrebbe essere notevolmente lenta nella pratica, ma se trovi un modo per fare tutto con una singola cut
invocazione, è probabile che sia più veloce che fare la stessa cosa con la manipolazione delle stringhe nella shell.
Si noti che il punto di interruzione può variare molto tra i sistemi. Può dipendere dal kernel, da come è configurato lo scheduler del kernel, dal filesystem contenente gli eseguibili esterni, dalla quantità di CPU rispetto alla pressione di memoria presente al momento e da molti altri fattori.
Non chiamare expr
per eseguire l'aritmetica se sei preoccupato per le prestazioni. In effetti, non chiamare expr
per eseguire l'aritmetica. Le conchiglie hanno un'aritmetica integrata, che è più chiara e più veloce di invocare expr
.
Sembra che tu stia usando bash, dato che stai usando costrutti bash che non esistono in sh. Quindi perché mai non dovresti usare un array? Un array è la soluzione più naturale ed è probabilmente anche la più veloce. Si noti che gli indici di array iniziano da 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
Il tuo script potrebbe essere più veloce se usi sh, se il tuo sistema ha dash o ksh come sh
anziché bash. Se si utilizza sh, non si ottengono array denominati, ma si ottiene comunque l'array uno dei parametri posizionali, con cui è possibile impostare set
. Per accedere a un elemento in una posizione che non è nota fino al runtime, è necessario utilizzare eval
(fare attenzione a citare le cose correttamente!).
# 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
Se si desidera accedere all'array solo una volta e si va da sinistra a destra (saltando alcuni valori), è possibile utilizzare shift
invece di indici variabili.
# 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
L'approccio più rapido dipende dalla shell e dal numero di elementi.
Un'altra possibilità è utilizzare l'elaborazione delle stringhe. Ha il vantaggio di non usare i parametri posizionali, quindi puoi usarli per qualcos'altro. Sarà più lento per grandi quantità di dati, ma è improbabile che faccia una differenza evidente per piccole quantità di dati.
# 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