C#)からコンパイル後どういう実装が行われているかを知る事でC#を更に理解していきたいと思います。C#とは?簡単に説明すると、コンパイル時に生成されるILコードが分からなくてもILコードをC#に変換すれば理解しやすくて便利だよね。内部ではstring.Concatに変換されていました。内部ではstring.Formatに変換されていました。TestClass気になったのでパフォーマンスチェック+での連結と$での文字列補間で内部の実装が違うので、変数の埋め込みと文字列の連結をテストしてみました。変数の埋め込みパフォーマンス的にはstring.Concatが若干早いです。文字列補間は、フォーマットが間違っていた場合コンパイルエラーとして検出してくれるのでフォーマットを使う場合は優先したいです。文字列の連結パフォーマンス的に、+で繋げた方が良さそうです。num;}今回は、2つの方法を比較したかったので除外しましたが、頻繁に文字列の連結が必要ならStringBuilderを検討した方が良いです。暗黙的変換Vector2の変数にVector3を代入するとVector2に自動的に変換してくれます。operatorを呼んでいるようです。operatorのようです。Vector2を実行している事が分かりました。newする度にほんの僅かですがコストがかかるので、例えば2Dゲームでもtransform.positionへの代入はVector3をメインに使った方が良さそうです。v.y);CoroutineCoroutineを使うと内部で自動生成されたIEnumeratorを実装したクラスを使用している事が分かります。Allocが発生します。Allocで書けなかったので残念です。掲載するか迷いましたが、今後の自分の為に掲載します。下記の結果は2回目以降の数値です。値型を参照型であるobject型にキャストすると値型から参照型へ変換するボックス化が発生します。身近なところで言うとDebug.Logに数値などの値型を入れるとボックス化が発生します。それだけでは無く重い処理の為なるべくDebug.Logはコードに残さない方が良いです。TestClassDebug.Logを残したい値の確認やエラーチェックなど、何らかの理由でDebug.Logを残したい事もあると思います。Buildのみ有効にするのをおすすめします。Buildのみで機能します。Debug.Log(message);}ラムダ式ローカル変数をラムダ式内で使うと、GCゴミが発生します。理由は内部でクラスが自動生成されていて、そのクラスを利用する為に発生します。TestClassラムダ式内にローカル変数を移動できるのであれば、自動生成されたクラスがキャッシュされるので2回目以降使い回してくれます。TestClass結論ローカル変数はできる限りラムダ式内に書くのがパフォーマンスが良い。});}タプルタプルは内部でValueTupleに変換してくれるようです。引数が少ないメソッドやシグネイチャの変更が発生しても問題無い場合は、積極的に使っていきたいです。ValueTupleは値型なのでモバイルでパフォーマンスを優先したい箇所でも使えそうです。TestClassEnumEnumは++でインクリメントできます。中身を確認するとintに置き換わっている事が分かりました。}}そして、数値が振られていない場合、自動的に0から始まる連番で初期化されるようです。下記のようなイメージです。2}内部を知れば下記の意味が理解できます。基になる整数値型の一連の名前付き定数によって定義された値の型です。C#では確認出来なかったのでILコードを確認ください。TestClassEnumをシリアライズして使う場合、正しく値を変更しないとおかしくなります。E3}}変更後E1の前にE4を追加すると、選択されている値がE4に変わってしまいます。シリアライズするとenumの名称は無視され値の整数しか見ない為にこの問題が発生します。E3}}どうしたら良いか?下記のように定義するのがおすすめです。自動で振られる連番をあえて自分で振って、強い意志をアピールするのが効果的です。2}セーブデータとしてenumを保存する際も必ずシリアライズが必要になり同じ問題が発生するので注意が必要です。個人的には外部に公開する場合や、インスペクタに表示する場合は整数を振るようにしてます。GameObjectのnullチェックUnityの==演算子は特殊なので内部でどうなっているのか調べてみました。==でnullチェック内部的には、Object.op_Equalityで比較している事が分かりました。内部では、Object.IsNativeObjectAliveでGameObjectがシーン上に存在するか確認する処理が実行されています。rhs.m_InstanceID;}null合体演算子での確認null合体演算子でチェックした場合、先ほどのObject.op_Equalityが使われていません。Object.op_Equalityで確認していない。オブジェクトが削除されていても結果がtrueになる可能性があります。UnityのGameObjectは必ず==でnullチェックする必要があります。Null条件演算子も同じです。MyScriptにはMonoBehaviourが継承されています。Object.op_Equalityで確認していない。MyScriptにはMonoBehaviourが継承されています。TestClass分かり易いように馴染み深いGameObjectで話を進めましたが、UnityEngine.Objectを継承するComponentクラスはすべて==でnullチェックする必要があります。C#であればいつも通りに読めるので解析しやすかったです。あと、今まで知っていた事でも読めるコードにすると理解しやすくて良いですね。今後もパフォーマンスを追い込む必要がある箇所や効率の良い書き方の発掘などで使っていきたいと思います。最後まで読んでいただきありがとうございました。