好吧,我想我找到了一些關於這個問題的解決方案。我做了3個測試,我在這裏添加一個簡單的示例。我認爲第二對我來說是最好的,但我決定做一個加載測試。
public class CallTest {
public void TestCode() {
var items = new List<CallKeyValue>
{
new CallKeyValue {CallKey = CallKey.CallDate, Value1 = "11.04.2017"},
new CallKeyValue {CallKey = CallKey.CallTime, Value1 = "15:43"},
new CallKeyValue {CallKey = CallKey.FromPhoneNumber, Value1 = "5311234567"},
new CallKeyValue {CallKey = CallKey.ToPhoneNumber, Value1 = "5311234587 "},
new CallKeyValue {CallKey = CallKey.Duration, Value1 = "13*min"},
new CallKeyValue {CallKey = CallKey.FromOperatorCode, Value1 = "TR",Value2 = "001"},
new CallKeyValue {CallKey = CallKey.ToOperatorCode, Value1 = "TR",Value2 = "002"},
};
var st = new Stopwatch();
//Test 1: ElapsedMilliseconds: 50, ElapsedTicks: 122023
st.Start();
IDictionary<string,dynamic> expando = new ExpandoObject();
foreach(var item in items) {
expando.Add(item.CallKey.ToString(),null);
expando[item.CallKey.ToString()] = new { Value1 = item.Value1,Value2 = item.Value2 };
}
var cd = new CallDetail {
CallDate = DateTime.Parse(expando[CallKey.CallDate.ToString()].Value1 + " " + expando[CallKey.CallTime.ToString()].Value1),
FromPhoneNumber = expando[CallKey.FromPhoneNumber.ToString()].Value1,
ToPhoneNumber = expando[CallKey.ToPhoneNumber.ToString()].Value1,
Duration = Convert.ToInt32(expando[CallKey.Duration.ToString()].Value1.ToString().Split('*')[0]),
DurationUnit = GetEnumKeyOfUnit(expando[CallKey.Duration.ToString()].Value1.ToString().Split('*')[1]),
FromOperatorCountry = expando[CallKey.FromOperatorCode.ToString()].Value1,
FromOperatorId = expando[CallKey.FromOperatorCode.ToString()].Value2,
ToOperatorCountry = expando[CallKey.ToOperatorCode.ToString()].Value1,
ToOperatorId = expando[CallKey.ToOperatorCode.ToString()].Value2
};
st.Stop();
Console.WriteLine(st.ElapsedMilliseconds);
Console.WriteLine(st.ElapsedTicks);
st.Reset();
//Test 2: ElapsedMilliseconds: 0, ElapsedTicks: 328
st.Start();
var cd3 = items.Select(s => {
IDictionary<string,dynamic> expando2 = new ExpandoObject();
expando2.Add(s.CallKey.ToString(),null);
expando2[s.CallKey.ToString()] = new { Value1 = s.Value1,Value2 = s.Value2 };
var item = new CallDetail {
CallDate = DateTime.Parse(expando2[CallKey.CallDate.ToString()].Value1 + " " + expando2[CallKey.CallTime.ToString()].Value1),
FromPhoneNumber = expando2[CallKey.FromPhoneNumber.ToString()].Value1,
ToPhoneNumber = expando2[CallKey.ToPhoneNumber.ToString()].Value1,
Duration = Convert.ToInt32(expando2[CallKey.Duration.ToString()].Value1.ToString().Split('*')[0]),
DurationUnit = GetEnumKeyOfUnit(expando2[CallKey.Duration.ToString()].Value1.ToString().Split('*')[1]),
FromOperatorCountry = expando2[CallKey.FromOperatorCode.ToString()].Value1,
FromOperatorId = expando2[CallKey.FromOperatorCode.ToString()].Value2,
ToOperatorCountry = expando2[CallKey.ToOperatorCode.ToString()].Value1,
ToOperatorId = expando2[CallKey.ToOperatorCode.ToString()].Value2
};
return item;
});
st.Stop();
Console.WriteLine(st.ElapsedMilliseconds);
Console.WriteLine(st.ElapsedTicks);
st.Reset();
//Test 3: ElapsedMilliseconds: 0, ElapsedTicks: 1390
st.Start();
var cd2 = new CallDetail {
CallDate = DateTime.Parse(items.FirstOrDefault(f => f.CallKey == CallKey.CallDate)?.Value1 + " " + items.FirstOrDefault(f => f.CallKey == CallKey.CallTime)?.Value1),
FromPhoneNumber = items.FirstOrDefault(f => f.CallKey == CallKey.FromPhoneNumber)?.Value1,
ToPhoneNumber = items.FirstOrDefault(f => f.CallKey == CallKey.ToPhoneNumber)?.Value1,
Duration = Convert.ToInt32(items.FirstOrDefault(f => f.CallKey == CallKey.Duration)?.Value1.Split('*')[0]),
DurationUnit = GetEnumKeyOfUnit(items.FirstOrDefault(f => f.CallKey == CallKey.Duration)?.Value1.Split('*')[1]),
FromOperatorCountry = items.FirstOrDefault(f => f.CallKey == CallKey.FromOperatorCode)?.Value1,
FromOperatorId = items.FirstOrDefault(f => f.CallKey == CallKey.FromOperatorCode)?.Value2,
ToOperatorCountry = items.FirstOrDefault(f => f.CallKey == CallKey.ToOperatorCode)?.Value1,
ToOperatorId = items.FirstOrDefault(f => f.CallKey == CallKey.ToOperatorCode)?.Value2
};
st.Stop();
Console.WriteLine(st.ElapsedMilliseconds);
Console.WriteLine(st.ElapsedTicks);
}
private DurationUnit? GetEnumKeyOfUnit(string unit) {
switch(unit) {
case "min":
return DurationUnit.Minute;
case "hour":
return DurationUnit.Hour;
}
return null;
}
}
在此測試之前,我嘗試使用反射。反射性能比3次測試差。這是elapsedmilliseconds約爲100,也elatedticks非常高。我可以使用第二個測試,直到找到更好的方式。
如果你可以在這裏提供一些背景,這可能是有益的。你想在這裏解決什麼問題? – jcb
我有一個性能問題。這只是一個例子,但我有更多的數據。反思是一個很好的解決方案,但我認爲(可能是我的方式錯了,我不確定),這很慢。 –
反思本身可能不起作用(除非你正在做的事情比你的問題更明顯)。例如,您需要了解'CallDetail'來確定「CallKey.Duration」類型的字符串「13 * min」將需要拆分爲'CallDetail.Duration'和'CallDetail.DurationUnit'。前者可以通過搜索相同名稱的屬性來找到,但後者以任何方式都不明顯(再次,除非有更多元信息可用,通用反映解決方案可以訪問)。 – jcb