【C#】BinaryFormatterを用いた配列のコピーはかなり遅い
結論
配列をディープコピーしたいのであれば、一つずつコピーした方が良いです。
経緯
C#では、クラスの配列をArray.Copyしたときシャローコピーになります。正確に言うと、2階層目からシャローコピーになります。1次元の配列であれば、Array.Copyでディープコピーになりますが、リストのリストといった2階層目があると2階層目からシャローコピーになります。リストのリストをディープコピーしたかったので、このような方法を用いました。
public static T DeepCopyT<T>(T target) { T result; BinaryFormatter b = new BinaryFormatter(); MemoryStream mem = new MemoryStream(); try { b.Serialize(mem, target); mem.Position = 0; result = (T)b.Deserialize(mem); } finally { mem.Dispose(); } return result; }
BinaryFormatterでMemoryStreamをシリアライズ・デシリアライズすることで、コピーしたものを返しています。 今回私がこのメソッドに渡していた配列は、class[1000]でした。クラスはa[23].b[20].c[8]個の構造でした。これを上記のメソッドに丸ごとクラスの配列を渡すと、 何と2分かかりました。さすがに実用に耐えないということで、対策を調べるとBinaryFormatterの配列のシリアライズ・デシリアライズは遅いということが分かりました。よって
for(int i=0;i<class.Length;i++) { copyArray[i] = DeepCopy.DeepCopyT(class[i]); }
として一つずつ渡すようにすると20秒で終わりました。