私は何千もの単語のリストから4ワードのランダムなパスフレーズを生成する単純なbashスクリプトを作りました。今私は個人的な使用のために本当に安全であるか効率的であるかどうかはわかりません。しかし、それは主要なポイントではありません。それをチェックアウト - >異なる引数を使って同じ関数を何回も呼び出すのが遅いのはなぜですか?
を、私は私のラップトップでそれを実行するときに、入力と出力は次のようになります。
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つの単語ごとに1つずつ、別の引数で呼び出す必要があります。私は本当に速いと思った。ここで
は、コード変更である:今ここに
# 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
タイミングの違いはそれほど大きくありません全体的には間違いなくもっと速いと思った。
なぜ、2番目のスクリプトが最初のスクリプトより遅いのですか?
、「占星術"と" overstay "は形容詞ではありません。あなたのルールには微調整が必要です。 – tripleee
本当に問題ではありませんが、ランダム性が重要です。私は実際にそれらの "動詞 - 名詞"のことをスキップして、スクリプトに4つの全くランダムな単語を出力させることができましたが、私はそれが甘いと思っていました。ルールを調整するか、取り除くかのどちらかです。確かに速くそれらを取り除くだろうか。しかし、甘いものではありません... –
1. awkを何度も呼び出す必要がある場合は、awkでスクリプト全体をスクリプト化してください。 2.とにかく、同じファイルを何度も解析しているなら、間違ったことをしていることは間違いありません。 3.配列からランダムな要素を取得するために 'awk'を使用しないでください。それは本当に愚かです。配列の任意のフィールドに直接アクセスできます。 4.「参照」が必要だと思うなら( 'declare -a list_a =(" $ {!1} ")')、デザインが間違っているか、仕事の言語が間違っています。シェルスクリプトはそのような機能を使用すべきではありません。 –