今更ながら、PMillマクロコードの書き方の違いでの実行速度の違いを
比較してみました。
適当なツールパスを20本作り、
・tool.name
・Rapid.IncrementalStartZ
・Thickness
の3項目を抜き出します。
〇テスト1
全てのツールパスをforeachでグルグル回し、取得したパラメータを
String型に追加していきます。ベタベタなヤツです。
foreach tp in folder('toolpath') { $toolname = $toolname + ',' + $tp.tool.name $rapid = $rapid + ',' + $tp.Rapid.IncrementalStartZ $thickness = $thickness + ',' + $tp.Thickness }
rapid と thickness は本来Real型なのですが、何故かString型にStringとして
追加出来ました。暗黙変換でしょうか? 危険ですね・・・。
確か、多くの言語はString型に追加された際には、既存の文字分+追加分
の領域を新たに確保しコピーした後に、追加分が入るような処理をしていた
ような気がしたので、安易に考えても効率悪そうです。
〇テスト2
foreachでグルグル回し、String型に追加するのではなく一旦Listに
確保し、最後にJoinします。
foreach tp in folder('toolpath') { $dmy = add_last($toolnameLst, $tp.tool.name) $dmy = add_last($rapidLst, string($tp.Rapid.IncrementalStartZ)) $dmy = add_last($thicknessLst, string($tp.Thickness)) } string test2a = join($toolnameLst, ',') string test2b = join($rapidLst, ',') string test2c = join($thicknessLst, ',')
String型に追加しない分Joinの処理があるので、どちらが効率が良いものか?
〇テスト3
グルグルやるのを止め、関数を利用し狙ったパラメータをガツンと抜き出しJoinします。
$toolname2 = join(extract(folder('toolpath'), 'tool.name'), ',') $rapid2 = join(extract(folder('toolpath'), 'Rapid.IncrementalStartZ'), ',') $thickness2 = join(extract(folder('toolpath'), 'Thickness'), ',')
2つの作業を1行で行うので、コード自体も短いです。
全体的にはこんな感じです。
//pm2018 macro function main() { string tm = '' string list msg = {} int dmy = 0 //test1 string toolname = '' string rapid = '' string thickness = '' call Sw_Start() foreach tp in folder('toolpath') { $toolname = $toolname + ',' + $tp.tool.name $rapid = $rapid + ',' + $tp.Rapid.IncrementalStartZ $thickness = $thickness + ',' + $tp.Thickness } call Sw_GetTime($tm) $dmy = add_last($msg, 'test1 :' + $tm) //test2 string list toolnameLst = {} string list rapidLst = {} string list thicknessLst = {} call Sw_Start() foreach tp in folder('toolpath') { $dmy = add_last($toolnameLst, $tp.tool.name) $dmy = add_last($rapidLst, string($tp.Rapid.IncrementalStartZ)) $dmy = add_last($thicknessLst, string($tp.Thickness)) } string test2a = join($toolnameLst, ',') string test2b = join($rapidLst, ',') string test2c = join($thicknessLst, ',') call Sw_GetTime($tm) $dmy = add_last($msg, 'test2 :' + $tm) //test3 string toolname2 = '' string rapid2 = '' string thickness2 = '' call Sw_Start() $toolname2 = join(extract(folder('toolpath'), 'tool.name'), ',') $rapid2 = join(extract(folder('toolpath'), 'Rapid.IncrementalStartZ'), ',') $thickness2 = join(extract(folder('toolpath'), 'Thickness'), ',') call Sw_GetTime($tm) $dmy = add_last($msg, 'test3 :'+ $tm) message info join($msg, crlf) } //clock on function Sw_Start() { CLOCK RESET QUIT CLOCK ON QUIT } //clock off function Sw_GetTime(output string out) { string $TraceFilePath = macro_path(false) + "\clock.txt" string list txts = {} ECHO OFF DCPDEBUG UNTRACE COMMAND ACCEPT TRACEFILE OPEN $TraceFilePath CLOCK OFF QUIT CLOCK PRINT QUIT TRACEFILE CLOSE ECHO ON DCPDEBUG TRACE COMMAND ACCEPT FILE OPEN $TraceFilePath FOR READ AS Input FILE READ $txts FROM Input FILE CLOSE Input DELETE FILE $TraceFilePath $out = $txts[0] }
圧倒的です。
過去にこちらを書きましたが、
PowerMillマクロを高速化? - C#ATIA
個人的には
GRAPHICS LOCK GRAPHICS UKLOCK
は、ほぼ効果無いです。CATIAの様に面等を選択した際のハイライトを
止めてもらえる方が効果が有りそうな気もするのですが。
(大きな計算済みツールパスを、アクティブにしなければならない)
他にも、モデルを非表示、エクスプローラ-を非表示等試した事も有りますが
ほぼ効果がありません。
foreach piyo in hoge { if huga { dmy = add_last(lst, piyo.name) } }
のような処理は
lst = extract(filter(hoge, huga), 'name')
のようなコードにした方が、圧倒的に速いです。(VBAにも欲しい)
これの逆で、同一パラメータに同一の値を設定する関数無いかなぁ。