PowerShell -Part 5at TECH
PowerShell -Part 5 - 暇つぶし2ch996:デフォルトの名無しさん
22/02/13 20:32:19.65 zeKJdxT+.net
色々アドバイスありがとうございました。
それもそだな、と下記でいけました。お騒がせいたしました
$Excel = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
$Excel.ActiveWorkbook.ActiveSheet.name

997:デフォルトの名無しさん
22/02/21 13:09:23.89 jIppNsU3.net
教えて下さい
powershellで再帰処理をしたいんですが、
"The script failed due to call depth overflow"
と言うエラーで最後まで処理してくれません。
再帰回数のスタックオーバーフローで
トランポリン処理が有効とまでは調べたのですが
上手く理解出来ず
↓↓
URLリンク(qiita.com)
詳しい方、よろしくお願いします

998:デフォルトの名無しさん
22/02/21 13:24:10.95 Vv5lB4cH.net
そのメッセージの言わんとするところは、すげー効率悪いので再帰で書くな
というアドバイスです

999:デフォルトの名無しさん
22/02/21 13:39:08.84 jIppNsU3.net
対象データが階層構造になっていて、
網羅的に処理したいんですが、うーん

1000:デフォルトの名無しさん
22/02/21 14:08:41.32 Vv5lB4cH.net
500階層あるデータ構造はさすがに扱ったことがない…
そもそも特定の枝が底なし沼なのだとしたら、それでも延々と潜り続ける、というのは本当に意図した挙動なのか?
底なし沼が時々存在して、それに興味が無いのならば素直な余再帰で書ける幅優先探索を勧める
深さ優先で頑張りたいなら、スタックとしてコールスタックを流用するのでなくて、明示的にスタックにpush/popすると少しは経済的
特定の深さに達したら諦める決め打ちもあり
トランポリンで遅延�


1001:]価を積む利点は、入力データ構造を処理するというより、需要に応じて任意の深さのデータを出力できるという点にあるので、悪手かと



1002:デフォルトの名無しさん
22/02/21 14:17:30.40 +uSXi1Gh.net
トランポリン?のやってることはSchemeで言うCPS相当だね。まずCPSを理解しないと何が起きてるのか判らないと思う。
であるならば理屈ではトランポリンなんて変な事しなくてもスクリプトブロックをクロージャにするやつだけで再帰をクロージャの連鎖呼び出しに置き換えることはできると思う。

1003:デフォルトの名無しさん
22/02/21 14:38:31.70 Vv5lB4cH.net
(実装は暗黙のCPSかもしれないけど) schemeだとdelay/forceそのまんまじゃね
イテレータとかストリームとか色んな言い方があるけど、何にせよ処理すべきデータがまだ存在していないような時にのみ有効
もし処理対象のデータが既に存在しているのなら、単に無駄な計算を増やすだけだよ

1004:デフォルトの名無しさん
22/02/21 14:43:51.48 +uSXi1Gh.net
再帰処理したいつってる本人が理解できないと意味ないからな
再帰が軽い言語で処理すりゃいいんじゃねーの

1005:デフォルトの名無しさん
22/02/21 15:22:36.66 002PyiUh.net
コールスタック制限してない言語の方が珍しいと思うがね、スクリプト言語なら500-1000くらいが標準的か
とりあえず言語によって課される安全装置としてのコールスタック制限を回避したいのなら、>>984が求めている資料はこれだと思うURLリンク(www.python.org)(pwshじゃなくてすまん)
生リスト(配列)を使ってもいいけど、現実的な時間で可能なのか怪しい程の難問なので、これの出番かも
URLリンク(docs.microsoft.com)
URLリンク(docs.microsoft.com)

1006:デフォルトの名無しさん
22/02/21 15:34:29.48 002PyiUh.net
ごめんdfsだわこれ
全要素網羅したい、という要求だからどっちでもいいと思うけど
queueはこれ使うと配列よりかなり速いはず
URLリンク(docs.microsoft.com)

1007:デフォルトの名無しさん
22/02/21 16:03:11.06 jIppNsU3.net
すみません、めちゃくちゃ難しいっす
なんとなくリンク先のスクリプトが
動かせればと思ったのですが…
やはり悪手なんですかね

1008:デフォルトの名無しさん
22/02/21 16:22:43.74 Vv5lB4cH.net
データのサンプル、期待する出力を書いてくれれば具体的なコード提案できるかも(たぶん)

1009:デフォルトの名無しさん
22/02/21 18:40:11.40 jIppNsU3.net
色々回答してありがとうございました
結局再帰を使わずループで代用する
こととしました
トランポリンはもう少し
勉強してみたいと思います

1010:デフォルトの名無しさん
22/02/21 20:07:10.97 +uSXi1Gh.net
powershell内でC#埋め込めばいいんじゃないの
あいにくpowershellのクロージャはダイナミックスコープで使えたもんじゃないのでC#のサンプルだけ
Add-Type -TypeDefinition @"
using System;
public static class test {
 static int fib(int n) { //普通の再帰
  if (n < 2) {
   return n;
  } else {
   return fib(n - 1) + fib(n - 2);
  }
 }
 static void fibcps(int n, Action<int> cont) { // CPS(継続渡しスタイル)
  if (n < 2) {
   cont(n);
  } else {
   fibcps(n - 1, n1 =>
    fibcps(n - 2, n2 =>
     cont(n1 + n2)));
  }
 }
 public static void recurse() {
  for (var n = 0; n <= 20; ++n) {
   Console.WriteLine("fib {0}: {1}",n,fib(n)); //普通の再帰
   fibcps(n, r => Console.WriteLine("fibcps {0}: {1}",n,r)); // CPS(継続渡しスタイル)
  }
 }
}
"@
[test]::recurse()

1011:デフォルトの名無しさん
22/02/21 21:16:04.35 +uSXi1Gh.net
一応powershell版。ただしpowershell関数は末尾再帰の最適化をしてくれないためCPSで書いてもただの効率悪い再帰にしかならない。
上のC#も32bit環境だと末尾再帰の最適化が働かないため64bit環境でのみ有効なコード。
function fib($n) {
 if ($n -lt 2) {
  $n
 } else {
  (fib ($n - 1)) + (fib ($n - 2))
 }
}
function fibcps($n, $cont) {
 if ($n -lt 2) {
  & $cont $n
 } else {
  fibcps ($n - 1) {param($fib1); $cont = $cont
   fibcps ($n - 2) {param($fib2);
    & $cont ($fib1 + $fib2) }.GetNewClosure()}.GetNewClosure()
 }
}
1..10 | %{ $r=fib $_; "fib($_):$r" }
1..10 | %{ fibcps $_ {param([int]$r) "fibcps($_):$r"}.GetNewClosure() }

1012:デフォルトの名無しさん
22/02/21 21:38:24.93 MnJW8OUO.net
変なやり方を広めようとするやつの典型例

1013:デフォルトの名無しさん
22/02/22 00:12:46.08 wYlI3N7E.net
あえて混乱させようとしてるようにしか思えない
仮に末尾最適化でシリアルなコードを得たとして、まさかそれが木の探索に有利だとでも?
呼び出しをstart-(thread)jobで行ってスレッド/プロセスをばら撒けば済む話じゃないの
コールスタック溢れるような計算であればあるほど、スケーラブルで高速

1014:デフォルトの名無しさん
22/02/22 02:35:33.30 LHZaRsEg.net
スタックを使わない再帰呼び出しならスタックは溢れないなw
個々の再帰呼び出しをStart-ThreadJob/Wait/Receiveで機械的に置き換えればとりあえず動く雛形にはなる
代わりにプロセス/スレッドが溢れるけど、スレッドなら単に順番待ちに入るだけで悪さはしない
個々のワーカーが自身の子をwaitしている限りはオーバーヘッドでしかないので、メインプロセスを設けStart時に-StreamingHostで直接報告を挙げさせるべき
長く走ってる枝を殺す等、最適化の可能性は大
メモ化や大域脱出程度で済むような問題には薦めない

1015:1001
Over 1000 Thread.net
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 341日 2時間 5分 41秒

1016:過去ログ ★
[過去ログ]
■ このスレッドは過去ログ倉庫に格納されています


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch