2015-09-15 5 views
0

Может ли кто-нибудь объяснить, в чем причина серьезного замедления при повторении массивов bash назад?Итерационное направление и производительность массива Bash

Пример:

time bash -c 'arr=();for i in {1..100000}; do arr+=($i);done; echo "Straight"; i=0;while (($i < 100000)); do current_element=${arr[$i]}; ((i++));done'

Straight 

real 0m0.270s 
user 0m0.269s 
sys 0m0.002s 

time bash -c 'arr=();for i in {1..100000}; do arr+=($i);done; echo "Reverse"; i=99999;while (($i > 0)); do current_element=${arr[$i]}; ((i--));done'

Reverse 

real 0m25.569s 
user 0m25.589s 
sys 0m0.008s 

Также

${arr[i-1]} + ${arr[i]} 

гораздо быстрее, чем

${arr[i]} + ${arr[i-1]} 

Спасибо за ваше время.

Edit:

Баш --version

GNU Баш, версия 4.3.42 (1) -release (x86_64-RedHat-Linux-гну)

+0

очень интересно. Я подозреваю, что только кто-то, кто знаком с реализацией bash, сможет дать ответ. Для тех, кто надеется получить интимное: http://git.savannah.gnu.org/cgit/bash.git/tree/ –

+0

Пожалуйста, добавьте версию bash на ваш вопрос. – Cyrus

+1

'bash'" массивы "на самом деле являются двусвязными списками, поэтому наивное ожидание состоит в том, что' {$ arr [$ i]} 'должно быть операцией O (n), увеличивается или уменьшается i. Похоже, что может быть какая-то оптимизация кеширования, которая делает доступ быстрее для увеличения 'i'. Это имеет смысл, учитывая, что основной случай использования - передать содержимое массива в качестве позиционных параметров. – chepner

ответ

1

Найдено некоторую информацию по вопросу.

Согласно http://www.tldp.org/LDP/abs/html/arrays.html

Массивы в Bash являются (циркулярно), связанные списки типа строки (символ *).

Я думаю, это означает, что прошедшие элементы запрашиваются с самого начала массива каждый раз, следовательно, замедление. (Например: если мы в I, для того, чтобы добраться до I-1, мы должны начать смотреть с 0)

Также найдена соответствующая должность с более некоторой информацией по этому вопросу: http://spencertipping.com/posts/2013.0814.bash-is-irrecoverably-broken.html