Почему вызов одной и той же функции много раз с разными аргументами происходит медленнее

Я создал простой скрипт bash, который генерирует случайные пароли из 4 слов из списка тысяч слов. Теперь я не уверен, действительно ли это безопасно или эффективно для моего личного использования, вы, ребята, дайте мне знать, если вы думаете о каких-либо улучшениях. Но это не главное. Проверьте это ->

Поэтому, когда я запускаю его на своем ноутбуке, ввод и вывод выглядят так:

time sh genpass
astrology cringe tingling massager

real    0m0.319s
user    0m0.267s
sys     0m0.077s

Второй раз:

$ time sh genpass
prankish askew siren fritter

real    0m0.318s
user    0m0.266s
sys     0m0.077s

Иногда это может быть довольно забавно.

Во всяком случае, это сценарий:

# EDITABLES ###########################################
target="/path/to/my/wordList.txt" 
# END EDITABLES #######################################

getWordList() {
  case $1 in
    "verb")  mawk '/ing$|ed$|en$/ {print $2}' $target ;;
    "adjective")  mawk '/y$|ish$/ {print $2}' $target ;;
    "noun")  mawk '!/ing$|ed$|en$|y$|ish$/ {print $2}' $target ;; 
    *) printf "%s" "'${1}' is an invalid argument." && echo && exit 1
  esac
}

pickRandomLineNumber() {
  # Get the list in an array
  declare -a list_a=("${!1}")
  # How many items in the list
  local length="${#list_a[@]}"
  # Generate a random number between 1 and the number of items in the list
  local number=$RANDOM 
  let "number %= $length"
  # Print the word at random line
  printf "%s\n" ${list_a[@]} | mawk -v line=$number 'NR==line {print}' 
}

read -ra verbList <<< $( getWordList verb )
verb=$(pickRandomLineNumber verbList[@])

read -ra adjectiveList <<< $( getWordList adjective )
adjective=$(pickRandomLineNumber adjectiveList[@])

read -ra nounList <<< $( getWordList noun )
noun1=$(pickRandomLineNumber nounList[@])
noun2=$(pickRandomLineNumber nounList[@])

printf "%s %s %s %s\n" "${adjective}" "${noun1}" "${verb}" "${noun2}"

Видите, где я должен создать массив для каждого типа слова? 3 типа, 3 массива. Я подумал о том, чтобы вставить этот код в функцию, поэтому мне просто нужно было вызвать эту функцию 4 раза, по одному для каждого из моих 4 слов, с другим аргументом. Я действительно думал, что это будет быстрее.

Вот изменение кода:

# EDITABLES ###########################################
target="/path/to/my/wordList.txt"  
# END EDITABLES #######################################

getWordList() {
  case $1 in
    "verb")  mawk '/ing$|ed$|en$/ {print $2}' $target ;;
    "adjective")  mawk '/y$|ish$/ {print $2}' $target ;;
    "noun")  mawk '!/ing$|ed$|en$|y$|ish$/ {print $2}' $target ;; 
    *) printf "%s" "'${1}' is an invalid argument." && echo && exit 1
  esac
}

pickRandomLineNumber() {
  # Get the list in an array
  declare -a list_a=("${!1}")
  # How many items in the list
  local length="${#list_a[@]}"
  # Generate a random number between 1 and the number of items in the list
  local number=$RANDOM 
  let "number %= $length"
  # Print the word at random line
  printf "%s\n" ${list_a[@]} | mawk -v line=$number 'NR==line {print}' 
}

#### CHANGE ####
getWord() {
  read -ra list <<< $( getWordList $1)
  local word=$(pickRandomLineNumber list[@])
  printf "%s" "${word}"
}

printf "%s %s %s %s\n" $(getWord adjective) $(getWord noun) $(getWord verb) $(getWord noun)

Теперь вот ввод / вывод:

$ time sh genpass
overstay clench napping palace

real    0m0.403s
user    0m0.304s
sys     0m0.090s

И опять:

$ time sh genpass
gainfully cameo extended nutshell

real    0m0.369s
user    0m0.304s
sys     0m0.090s

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

Так есть ли у вас идеи, почему второй скрипт медленнее, чем первый?

1 ответ

Решение

У вас есть больше кода, делающего больше вещей, и все это не нужно. Вот как сделать то, что вы пытаетесь сделать:

$ cat tst.awk
function grw(arr) {     # Get Random Word
    return arr[int(rand() * length(arr)) + 1]
}

{
    if ( /(ing|ed|en)$/ ) verbs[++numVerbs] = $0
    else if ( /(y|ish)$/ ) adjectives[++numAdjectives] = $0
    else nouns[++numNouns] = $0
}

END {
    srand()
    printf "%s %s %s %s\n", grw(adjectives), grw(nouns), grw(verbs), grw(nouns)
}

$ awk -f tst.awk words
overstay clench siren clench
$ awk -f tst.awk words
prankish nutshell tingling cameo
$ awk -f tst.awk words
astrology clench tingling palace

Выше был запущен файл "слов", созданный из примера вывода, который вы указали в своем вопросе:

$ cat words
askew
astrology
cameo
clench
cringe
extended
fritter
gainfully
massager
napping
nutshell
overstay
palace
prankish
siren
tingling
Другие вопросы по тегам