[過去ログ] シェルスクリプト総合 その31 (1002レス)
上下前次1-新
抽出解除 必死チェッカー(本家) (べ) 自ID レス栞 あぼーん
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
709(2): デフォルトの名無しさん [sage] 2019/10/01(火) 16:40:08.47 ID:8eIOCDAd(1/18) AAS
hoge () {
echo "Hello"
}
for i in $(seq 1000); do
hoge
a=$(hoge)
done
myfunc と a=$(myfunc) の実行時間の差はなんなん?標準出力を横取りするためだけにしてはコストが高いかな
簡単に思いつくのは横取りするためパイプでで別プロセスにしなきゃとかかな?
712(1): デフォルトの名無しさん [sage] 2019/10/01(火) 16:54:32.38 ID:8eIOCDAd(2/18) AAS
なるほど。ksh(だけが?)がなんか賢いかな。zsh他も差がある
714: デフォルトの名無しさん [sage] 2019/10/01(火) 17:10:13.56 ID:8eIOCDAd(3/18) AAS
違う人じゃね?同一人物だったらアレだけどw
715(1): デフォルトの名無しさん [sage] 2019/10/01(火) 18:59:48.82 ID:8eIOCDAd(4/18) AAS
>>712
zsh他も差があるは、>>709で体感できる差があるが正しいか
kshでも差があるね。ループ数増やせば体感できるほどの差となるね
718(4): デフォルトの名無しさん [sage] 2019/10/01(火) 19:26:55.18 ID:8eIOCDAd(5/18) AAS
>>716716(1): デフォルトの名無しさん [sage] 2019/10/01(火) 19:16:54.12 ID:fust4gpU(1/9) AAS
>>709
forkだよ。$( ) の部分がサブシェルになってて
多くのシェルではサブシェル = 別プロセス生成で実装されてる。
そのおかげでサブシェルの中でcdを実行したり変数を使ったりしても
呼び出し元は汚染されたりしない
kshはサブシェルの実装が最適化されていて
全てではないが、サブシェルの部分を同一プロセスで実行する。
独自で状態の保存と復帰を実装してるのだろう。
外部リンク[html]:codeday.me
kshは速いと言っちゃ速いんだが、その(複雑な?)仕組みのせいで
バグのもとになってたりする。ということを書いてあるページが
有ったんだがどこか忘れた。
内部関数なのにってとこがね&普通の他の言語とはやはり違うな(まあ当然だが)という(内部汚染とかこれの本題ではないっすよ)
zshはkshを習ってだけど、ちょこちょこ習えてないなあ。kshの否定面のレスだけど、kshは人に優しいとこもあるとも思うw
a=0
ls | while read line; do
[ "$line" = 'hoge' ] && a=1
done
[ a -eq 1 ] && ...
っていう見た目他の言語的では当たり前のがちゃんと動くというwまあ、異端だけど
とりあえず、どうしようもないそういうものということでいいのね。どうも
719(2): デフォルトの名無しさん [sage] 2019/10/01(火) 19:30:13.87 ID:8eIOCDAd(6/18) AAS
>>717717(1): デフォルトの名無しさん [sage] 2019/10/01(火) 19:25:21.59 ID:fust4gpU(2/9) AAS
遅い原因の本質は標準出力のキャプチャじゃないから
この二つでも違いがでる
hoge () {
:
}
for i in $(seq 1000); do
hoge
(hoge)
done
>>715
> kshでも差があるね。ループ数増やせば体感できるほどの差となるね
そうなんだよね。サブシェルのコストは以外と大きい。
だから変数に入れて使うことが目的とした関数は以下のように
グローバル変数を使って返したほうがずっと速いわけさ
hoge () {
RET=Hello
}
for i in $(seq 1000); do
hoge
a=$RET
done
せっかくですが、ちょい本題とは違うかな。そりゃ () は...
なんで内部関数なのにサブシェルになんのかねん、他の言語的感覚ではという
まあ、内部関数だろうと、() と同じで $() もサブシェルになるということをおっしゃっりたいのでしょうけど
どうも
721(1): デフォルトの名無しさん [sage] 2019/10/01(火) 19:41:25.43 ID:8eIOCDAd(7/18) AAS
>>720720(1): デフォルトの名無しさん [sage] 2019/10/01(火) 19:37:54.80 ID:fust4gpU(3/9) AAS
>>719
> なんで内部関数なのにサブシェルになんのかねん、
考え方が違う。
コマンド置換$( ) は「サブシェルを使用して実行する」という"仕様"なんだよ
なんでサブシェルになるのか?ではなく仕様でサブシェルにすると決まってる。
ただし別プロセスにするとは決まっていない。だから子プロセスとかいう既存の
名前ではなく、新たにサブシェルという用語を作った。
サブシェルの仕様としては、「サブシェル内で行った変数などの変更は呼び出し元には伝わらない。」
などがあるが、それを実現してるなら別の別プロセスでなくてもよい。
だけど別プロセスにするほうが実装が簡単だから多くのシェルではサブシェル=別プロセスになってる。
その続きなどを読んでよ。言われていることはすでに書いてあるんですけど
どうしようもないという結論が得られたのでw、
結局、こんなことにもそれなりの差があるんだから「常時それも無条件で」実行時間の差があるなんて気にするなんて無意味だなと
なにかそれが問題になったときに気にする対応すればいいだけだなという。のをそもそも言いたかったw
723(1): デフォルトの名無しさん [sage] 2019/10/01(火) 19:51:56.19 ID:8eIOCDAd(8/18) AAS
>>722722(1): デフォルトの名無しさん [sage] 2019/10/01(火) 19:44:28.64 ID:fust4gpU(4/9) AAS
>>718
> 内部関数なのにってとこがね
他の言語の場合、(基本的に)関数内の変数の変更は呼び出し元に反映されない。
つまりローカル変数になってるだろ?
それと同じなんだよ。POSIXの範囲ではlocalもtypesetもないから
シェルスクリプトにはローカル変数がない
ように思えるが、実はサブシェルを使うからローカル変数は必要ない。とも言える。
ローカル変数を実現するためのサブシェルと言える。
サブシェルの仕様としてローカル変数は必須の機能だが、別プロセスにするのは必須ではない。
サブシェル(別プロセス)と捉えるから仰々しくなってるが、
変数のローカル化と考えれば、内部関数内の変数をローカル化するってだけだから
「内部関数なのに」とは思わないだろ?
なにを教えてくれてるのか教えたいのかわからないです
内部変数?内部変数環境のことは言ってないです。他の言語でもの(内部)関数を呼ぶその返り値を使うって話なんですけど
内部変数云々ならhogeもサブシェルにしなくちゃじゃないですか?内部関数という言葉が悪かったならすまんすですけど
726(2): デフォルトの名無しさん [sage] 2019/10/01(火) 19:56:56.36 ID:8eIOCDAd(9/18) AAS
>>725725(1): デフォルトの名無しさん [sage] 2019/10/01(火) 19:53:21.70 ID:fust4gpU(6/9) AAS
>>723
> 内部変数云々ならhogeもサブシェルにしなくちゃじゃないですか?
使い分けるんだよ。
ローカル変数化したいならサブシェルを使う。
そうでないならサブシェルを使わないって。
なんか教えたがりのようですけど、ちょっと無理があるかなと
あくまでも「他の言語的感覚では」が前提、それとは違うというのの確認でしかないんですけど
使い分けるとかそもそも内部変数の話はしてないんですよ
728(1): デフォルトの名無しさん [sage] 2019/10/01(火) 20:02:16.96 ID:8eIOCDAd(10/18) AAS
そもそものそもそもは、bcの毎回起動するのに時間がかかるというので、せっっかくの標準で暗黙的にもマルチプロセスなのでサーバ&クラアント的に起動しとけばいいんじゃねと
trap 'exec 8>&-; exec 7>&-; rm -f from-server to-server' EXIT
mkfifo from-server
mkfifo to-server
exec 8<> to-server
exec 7<> from-server
< to-server bc -l > from-server &
calc () {
echo "$*" > to-server
read result < from-server
echo $result
}
てのを書いたのよ、単なる興味的にどれだけのコスト削減できるのかを試し確認するために。で、この一連の(他の言語的には)思ってもいなかったとこでコストがあるなと。その確認だけだよ。で、やっぱり>>721のようなことだなとw
729: デフォルトの名無しさん [sage] 2019/10/01(火) 20:02:43.57 ID:8eIOCDAd(11/18) AAS
>>727はいはい
731: デフォルトの名無しさん [sage] 2019/10/01(火) 20:10:22.49 ID:8eIOCDAd(12/18) AAS
はいはい。知っていることを延々と言われても。それも聞いてもいないのに
734: デフォルトの名無しさん [sage] 2019/10/01(火) 21:25:17.92 ID:8eIOCDAd(13/18) AAS
何がお怒りのなのかさっぱりですけどw
735(2): デフォルトの名無しさん [sage] 2019/10/01(火) 21:31:30.87 ID:8eIOCDAd(14/18) AAS
よくわからないが、他の言語で
func()
と
a = func()
で、こんな差があるのなんて、他にどの言語あるの?俺は知らない少々他の言語を知っているが
てか、そういうのは普通は「使えない」からそうならないようにするし、そもそもシングルプロセスを前提のが多いだろうから、他の一般的な言語でシェルスクリプトのようなのはちょっと思いつきません
func がまあ普通の速さなので、a = func もなんか他の方法があるのかなと。無いという確認はとれてお礼も言っているのになあ>>718で
関係ない(知っていることを)ことを延々とでいい加減してくれというのはあったけどw
738: デフォルトの名無しさん [sage] 2019/10/01(火) 22:01:17.19 ID:8eIOCDAd(15/18) AAS
>>736相変わらずだね。何を言いたいのかさっぱり
返り値を使う(関数)使わない(サブルーチン)でコストがこんなにあるって話なのに
739: デフォルトの名無しさん [sage] 2019/10/01(火) 22:14:23.82 ID:8eIOCDAd(16/18) AAS
そうだ、ksh(zsh)ならreadでと思ったら、逆に遅くなるのね
hoge | read a
サブシェルになるのはhoge。kshはパイプでもパイプを使わずになんちゃらを使ってなんとかかんとかwとかあったからちょっと期待したのに
あれだな、そもそもシェルスクリプトの関数の返り値はreturnでの実行ステータスしかない、それ以外の形態(テキスト)は考えていませんからこんな感じにしかなりませんってとこか
743(3): デフォルトの名無しさん [sage] 2019/10/01(火) 23:53:15.78 ID:8eIOCDAd(17/18) AAS
return
なんすけど。returnの意味知ってる?とかいう。いや、しつれい
エラー情報でもない、単なる終了ステータス。exit ではないのは、まあ、関数だからと、exit と区別がつかないからかなw
744(3): デフォルトの名無しさん [sage] 2019/10/01(火) 23:59:02.30 ID:8eIOCDAd(18/18) AAS
function name () { }
が、POSIXではないのは(これからも採用されないかも?採用するの?)というのは、関数じゃねえー、所詮コマンドだなというとこかなと思ったりしてみたり、今回w
>>742742(2): デフォルトの名無しさん [sage] 2019/10/01(火) 23:35:42.98 ID:DttT1lmW(2/2) AAS
パイプで処理をつなげていくシェルスクリプトにおいて
返り値=出力なんだよ
出力を読み取って、処理して出力する
そういう基本がわかってないだけ
そのレベルで馬鹿にできるのはあなたがそのレベルと言っているようなもんかなとw
てか、return なのにそれを返り値と見るのを頭から否定するのは、いままでの同一人物としか思えないんだけど。シェルスクリプトは知っているがシェルスクリプトしか知らないシェルスクリプトにだけ拘るw
上下前次1-新書関写板覧索設栞歴
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.040s