C#ATIA

↑タイトル詐欺 主にCATIA V5 の VBA(最近はPMillマクロとFusion360APIが多い)

PMillマクロ速度比べ

今更ながら、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]
}

f:id:kandennti:20180530172816p:plain

圧倒的です。

過去にこちらを書きましたが、
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にも欲しい)
これの逆で、同一パラメータに同一の値を設定する関数無いかなぁ。