C# の System.Reflection に問題があります。データベースからデータを取得し、そのデータを JSON 文字列で取得しています。リフレクションを使用して、JSON から自己宣言されたオブジェクトにデータを処理する独自の実装を作成しました。ただし、通常は 50 ~ 100 個のオブジェクトの配列を持つ JSON 文字列を取得するため、リフレクションで使用しているループのために、プログラムの実行が非常に遅くなります。
反映が遅いと聞いたことがありますが、それほど遅くはないはずです。JSON.NET シリアライザーを使用する別のプロジェクトがあり、同じ出力 (1 秒未満) で問題なく実行されるリフレクションを使用してオブジェクトを少し異なる方法でインスタンス化する別のプロジェクトがあるため、実装に何か問題があると感じています。 50 個のオブジェクトで約 10 秒。
以下は、データを保存するために使用しているクラスです
class DC_Host
{
public string name;
public void printProperties()
{
//Prints all properties of a class usign reflection
//Doesn't really matter, since I'm not usign this for processing
}
}
class Host : DC_Host
{
public string asset_tag;
public string assigned;
public string assigned_to;
public string attributes;
public bool? can_print;
public string category;
public bool? cd_rom;
public int? cd_speed;
public string change_control;
public string chassis_type;
//And some more properties (around 70 - 80 fields in total)
以下に、リスト内に格納されているオブジェクトに情報を処理するためのメソッドを示します。JSON データは、JSON 入力で定義された配列オブジェクトごとに別のディクショナリを含むディクショナリ内に保存されます。JSON のデシリアライズは数ミリ秒で行われるため、問題は発生しません。
public List<DC_Host> readJSONTtoHost(ref Dictionary<string, dynamic> json)
{
bool array = isContainer();
List<DC_Host> hosts = new List<DC_Host>();
//Do different processing on objects depending on table type (array/single)
if (array)
{
foreach (Dictionary<string, dynamic> obj in json[json.First().Key])
{
hosts.Add(reflectToObject(obj));
}
}
else
{
hosts.Add(reflectToObject(json[json.First().Key]));
}
return hosts;
}
private DC_Host reflectToObject(Dictionary<string,dynamic> obj)
{
Host h = new Host();
FieldInfo[] fields = h.GetType().GetFields();
foreach (FieldInfo f in fields)
{
Object value = null;
/* IF there are values that are not in the dictionairy or where wrong conversion is
* utilised the values will not be processed and therefore not inserted into the
* host object or just ignored. On a later stage I might post specific error messages
* in the Catch module. */
/* TODO : Optimize and find out why this is soo slow */
try
{
value = obj[convTable[f.Name]];
}
catch { }
if (value == null)
{
f.SetValue(h, null);
continue;
}
// Het systeem werkt met list containers, MAAAR dan mogen er geen losse values zijn dus dit hangt
// zeer sterk af van de implementatie van Service Now.
if (f.FieldType == typeof(List<int?>)) //Arrays voor strings,ints en bools dus nog definieren
{
int count = obj[convTable[f.Name]].Count;
List<int?> temp = new List<int?>();
for (int i = 0; i < count; i++)
{
temp.Add(obj[convTable[f.Name]][i]);
f.SetValue(h, temp);
}
}
else if (f.FieldType == typeof(int?))
f.SetValue(h, int.Parse((string)value));
else if (f.FieldType == typeof(bool?))
f.SetValue(h, bool.Parse((string)value));
else
f.SetValue(h, (string)value);
}
Console.WriteLine("Processed " + h.name);
return h;
}
バックグラウンドでリフレクションを使用するための JSON.NET の実装が何であるかはわかりませんが、リフレクションを最適化するために欠けているものを使用していると思います。