Почему вызов одной и той же функции много раз с разными аргументами происходит медленнее
Я создал простой скрипт 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