我在C#中遇到System.Reflection的一些問題。我從數據庫中提取數據並以JSON字符串檢索數據。我已經使用Reflection將自己的JSON數據處理成我自己聲明的對象。然而,因爲我無意中得到一個JSON字符串和一個50到100個對象的數組,我的程序運行速度非常慢,因爲我正在使用反射循環。在將JSON字符串反序列化爲.NET對象時反射太慢
我聽說反射很慢,但它不應該這麼慢。我覺得有些東西在我的實現中是不正確的,因爲我有一個不同的項目,我使用JSON.NET序列化程序,並且實例化對象的方式與在同一輸出上運行得很好(不到一秒)的反射有點不同,而我的慢程序需要50個物體約10秒鐘。
下面是我classses,我使用存儲數據
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數據存儲在dictionairy中,該dictionairy包含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的執行是在後臺使用反射,但我assumign他們用我丟失的東西優化其反射。
爲了獲得最大性能,需要生成新代碼來填充數據。 – CodesInChaos 2012-07-27 07:48:36
但是即使沒有這些,充分利用字典和緩存應該會提高代碼的速度。 – CodesInChaos 2012-07-27 07:50:33
並擺脫空的捕獲。'TryGetValue' ftw – CodesInChaos 2012-07-27 07:51:16