この単純なコードは正常に動作し、それぞれUpdate/LateUpdate/FixedUpdate
関数の周りにBeginSample/EndSample
コールを追加できます。しかし、例えば条件の結果として、早期返却指示を考慮していない。 EndSampleコールがあらゆる状況下で実行されるように、早期復帰を考慮する同様の関数を書く方法を知っていますか?Cecilを使用して、関数の前後にbegin/endブロックを挿入します。
私はセシルの専門家ではないことに注意してください。私は今学んでいます。 InsertBefore
などの関数を呼び出すと、早く返される操作がCecilによって自動的に更新されるようです。したがって、オペコードがBR
のオペコードが以前に特定の命令アドレスにジャンプしていた場合、そのアドレスは挿入後に更新され、元の命令にジャンプします。これは大抵の場合は問題ありませんが、私の場合は、BR
操作が最後のRet
命令を直接指し示すので、if
ステートメントが最後に挿入された操作をスキップすることを意味します。 Update
,LateUpdate
およびFixedUpdate
はすべて無効関数であることに注意してください。ボーナスとして
foreach (var method in type.Methods)
{
if ((method.Name == "Update" || method.Name == "LateUpdate" || method.Name == "FixedUpdate") &&
method.HasParameters == false)
{
var beginMethod =
module.ImportReference(typeof (Profiler).GetMethod("BeginSample",
new[] {typeof (string)}));
var endMethod =
module.ImportReference(typeof (Profiler).GetMethod("EndSample",
BindingFlags.Static |
BindingFlags.Public));
Debug.Log(method.Name + " method found in class: " + type.Name);
var ilProcessor = method.Body.GetILProcessor();
var first = method.Body.Instructions[0];
ilProcessor.InsertBefore(first,
Instruction.Create(OpCodes.Ldstr,
type.FullName + "." + method.Name));
ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Call, beginMethod));
var lastRet = method.Body.Instructions[method.Body.Instructions.Count - 1];
ilProcessor.InsertBefore(lastRet, Instruction.Create(OpCodes.Call, endMethod));
changed = true;
}
}
、あなたは私に同じオペランドと新たに作成された命令Emit
とAppend
の違いを説明できるかどうか。 AppendはEmit
をフードの下で実行するのでしょうか?
Cecilについて何も知らないうちにクイックコメント:内部コントロールフローに関係なく常に何かが起こることを保証するには、すべての出口ポイントを狩るのではなく、「try .. finallyブロック」を実行するのは明らかです。別の明白なアプローチ(これと組み合わせる)は元の関数の名前を変更し、 'begin()/ function()/ end()'を実行するラッパーで完全に置き換えることです。最後に、ホイールを再開発するのではなく、プロファイラの使用を検討することができます。もちろん、自分の車輪が本当に必要なわけではありません。 –