Почему случаи переключения выполняются намного медленнее, чем операторы else if в Fish?

#bash #shell #if-statement #fish

#bash #оболочка #if-statement #fish

Вопрос:

Я написал fish функцию, которая возвращала каждому файлу/ подкаталогу каталога соответствующий значок.

https://cdn.discordapp.com/attachments/752253510795526175/783515933011869696/unknown.png

У меня была bash функция, которая делает то же самое, но написана с помощью оператора elif.

 lsi () {
  echo "   .. "
  if [[ "$1" != "" ]]; then
    echo "$1 here"
  fi
  ls $( echo $SHOW_HIDDEN | sed 's/true/-A/' | sed 's/false//') | while read entry; do
    if [ -d "(pwd)/$entry" ]; then
      echo "   $entry"
    elif [[ $entry =~ .(sh|c)$ ]]; then
      echo "   $entry"
    elif [[ $entry =~ .(md|txt|log)$|rc$ ]]; then
      echo "   $entry"
    elif [[ $entry =~ .(jpg|png|svg|webp)$ ]]; then
      echo "   $entry"
    elif [[ $entry =~ .fish$ ]]; then
      echo "   $entry"
    elif [[ $entry =~ .py$ ]]; then
      echo "   $entry"
    elif [[ $entry =~ .js$ ]]; then
      echo "   $entry"
    elif [[ $entry =~ .mp4|mkv$ ]]; then
      echo "辶   $entry"
    elif [[ $entry =~ .(mp3|m4a)$ ]]; then
      echo "   $entry"
    elif [[ $entry =~ .(pdf)$ ]]; then
      echo "   $entry"
    elif [[ $entry =~ .(tar|zip) ]]; then
      echo "遲    $entry"
    else
      echo "   $entry"
    fi
  done
}
 

Когда я провел некоторое тестирование в более крупных каталогах , таких как /usr/bin or even Pictures , bash скрипт был заметно быстрее , особенно на /usr/bin .

Я переписал оператор fish with else if

 function lsi --description "ls with icons"
  echo "   .. "
  if $SHOW_HIDDEN
    set all -A
  end
  if ! test -z $argv[1]
    echo $argv[1]
  end
  for entry in (ls $all)
    if test -d "$entry"
      echo "   $entry"
    else if string match -rq '.sh

и теперь они работают почти одинаково.

Я хотел бы знать, почему  switch/case  версия настолько медленнее. Это потому fish  , что встроенная функция плохая или она имеет какое-то отношение  switch/case  к общему?


Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:

 for entry in (ls $all)
  if ...
  else 
    switch (echo "$entry} | sed 's/.*.//')    # sub-process call for each file processed!!
    ...
  end
end 
 

Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:

 ls $( echo $SHOW_HIDDEN | sed 's/true/-A/' | sed 's/false//') | while read entry; do ...
 

Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...

 $ entry='abc.def.pdf'
$ echo "${entry##*.}"       # show file extension
pdf
 

... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:

 switch "${entry##*.}"
 

Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде

 switch $entry
    case '*.fish'
       # do the fish thing
    case '*.'{jpg,png,svg,webp,gif}
       # do the thing for images
end
 

и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.(md|txt|log)|rcи теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.(jpg|png|svg|webp|gif)

и теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.fishи теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.rs

и теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.(c|h)и теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.py

и теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.jsи теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.go

и теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.pdfи теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo " $entry"
else if string match -rq '.(mp4|mkv)

и теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo "辶 $entry"
else if string match -rq '.(tar|zip)и теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров...


... вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же - ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.

$entry
echo "遲 $entry"
else
echo " $entry"
end
end
end

и теперь они работают почти одинаково.

Я хотел бы знать, почему switch/case версия настолько медленнее. Это потому fish , что встроенная функция плохая или она имеет какое-то отношение switch/case к общему?

Ответ №1:

Я предполагаю, что более медленный switch код связан с вызовом подпроцесса ( echo | sed ), выполняемым для каждого файла:


Конечно, вы запускаете вызов подпроцесса ( echo|sed|sed ) в bash решении, но это одноразовый вызов в начале while цикла:


Ключевой проблемой здесь является количество вызовов подпроцессов, выполняемых с fish/switch помощью кода; с fish/switch кодом вы заметите длительное время выполнения er для действительно больших каталогов из-за увеличения количества вызовов подпроцессов.

Я не знаком, fish но если он поддерживает расширение параметров…


… вероятно, вы могли бы заменить вызов подпроцесса для повышения производительности, например:


Комментарии:

1. Он не поддерживает расширение параметров, обработка строк fish использует string встроенный. Однако в этом случае самым простым решением является просто использование сопоставления с case глобусом.

Ответ №2:

Вы не сравниваете одно и то же — ваш код fish выполняется sed один раз для каждого файла, для чего требуется настроить весь процесс, который является медленным.

string является встроенным, поэтому он запускается в процессе оболочки, что происходит быстро, поэтому ваша переписанная версия намного быстрее.

Кстати, fish case может обрабатывать глобусы, поэтому вы можете использовать что-то вроде


и удалите sed .

Комментарии:

1. Спасибо, я не знал case, и я подозреваю, что многие другие встроенные модули fish могли обрабатывать глобусы таким образом.