C# 比使用多个if语句检查字典中的键更有效的替代方法
我有大约45条if语句检查字典是否有那个键C# 比使用多个if语句检查字典中的键更有效的替代方法,c#,if-statement,C#,If Statement,我有大约45条if语句检查字典是否有那个键 private List<MessageName> createMsgObject(Dictionary<string, string> infoHash, Dictionary<string, Int16> msgDescritionAndID) { MessageName msgName = null; List<MessageName>
private List<MessageName> createMsgObject(Dictionary<string, string> infoHash, Dictionary<string, Int16> msgDescritionAndID)
{
MessageName msgName = null;
List<MessageName> msgNameList = new List<MessageName>();
var msgObjOuter = new MessageName();
if (infoHash.ContainsKey("redis_version"))
{
msgName = new MessageName();
msgName.MessageID = msgDescritionAndID["redis_version"];
msgName.DiagnosticCnt = 0;
msgName.DiagnosticStr = infoHash["redis_version"];
msgNameList.Add(msgName);
}
if (infoHash.ContainsKey("uptime_in_seconds"))
{
msgName = new MessageName();
msgName.MessageID = msgDescritionAndID["uptime_in_seconds"];
msgName.DiagnosticCnt = Convert.ToInt32(infoHash["uptime_in_seconds"]);
msgName.DiagnosticStr = "";
msgNameList.Add(msgName);
}
//... 40 more if statements
return msgNameList;
}
private List createMsgObject(字典infoHash、字典msgDescritionAndID)
{
MessageName msgName=null;
List msgNameList=新列表();
var msgObjOuter=新消息名();
if(infoHash.ContainsKey(“redis_版本”))
{
msgName=newmessagename();
msgName.MessageID=msgDescritionAndID[“redis_版本”];
msgName.DiagnosticCnt=0;
msgName.DiagnosticStr=infoHash[“redis_版本”];
msgNameList.Add(msgName);
}
if(infoHash.ContainsKey(“正常运行时间(秒)))
{
msgName=newmessagename();
msgName.MessageID=msgDescritionAndID[“正常运行时间(以秒计)”;
msgName.DiagnosticCnt=Convert.ToInt32(infoHash[“正常运行时间(以秒计)”);
msgName.DiagnosticStr=“”;
msgNameList.Add(msgName);
}
//…40多条if语句
返回msgNameList;
}
这对性能确实没有影响,但我想知道是否有更有效的方法来检查字典中的所有键,以及是否将其属性插入MessageName对象并将该对象插入列表。我不知道switch语句是否有助于提高性能 与多个ifs相比,Switch语句确实有助于提高性能 然而,我有一个建议,如果在您的40+语句中多次将相同的属性分配给相同的变量,您可以尝试以下方法:
List<string> toCheckStrings1 = new List<string> { "redis_version", "something similar", }; //you can put all the strings here first
由于您为某些变量指定了不同的属性(例如“正常运行时间(以秒计)”的DiagnosticCnt
),因此您可以对这些变量进行不同的分组:
List<string> toCheckStrings2 = new List<string> { "uptime_in_seconds", "others", "etc" };
foreach (var match in toCheckStrings2.Intersect(infoHash.Keys))
{
msgNameList.Add(new MessageName
{
MessageID = msgDescritionAndID[match],
DiagnosticCnt = Convert.ToInt32(infoHash["match"]),
DiagnosticStr = ""
});
}
List toCheckStrings2=新列表{“正常运行时间(以秒计)”、“其他”、“等”};
foreach(toCheckStrings2.Intersect(infoHash.Keys)中的变量匹配)
{
msgNameList.Add(新消息名
{
MessageID=msgDescritionAndID[match],
DiagnosticCnt=Convert.ToInt32(infoHash[“匹配]),
DiagnosticStr=“”
});
}
其他情况也是如此。即使它可能是几个foreach
循环,希望它比45个if语句少得多
编辑
正如在评论中指出的,我上面建议的时间复杂度大约在O(N)左右,而对于您的代码,它将是一堆O(1),基本上是O(1)。因此,如果时间是一个问题(如果你有大量的数据集),那么明智的做法是只使用
if
语句,或者switch
不需要对所有消息执行字典查找,除非你的字典有很多你不感兴趣的键,在这种情况下,坚持使用你所拥有的键
否则,您已经知道字典中有哪些键,因此可以直接枚举它们
对于那些在检查密钥后当前正在查找值的消息,您将取消另一次查找,因为枚举字典具有免费获取值的额外好处
然后,剩下要做的就是从第二个字典中查找int16,查找要处理的键
您可以更高效地处理此问题,并像这样减少代码基数(假设infoHash只有您想要的密钥):
private List createMsgObject(字典infoHash、字典msgDescritionAndID)
{
MessageName msgName=null;
List msgNameList=新列表();
var msgObjOuter=新消息名();
//不需要对40个变量执行infoHash的o(1)查找。
//您已经有一个包含密钥的列表,所以只需枚举它们。
foreach(infoHash中的KeyValuePair信息)
{
var msg=new MessageName(){MessageID=msgDescritionAndID[info.Key]};
开关(信息键)
{
//首先切换所有int16版本:
案例“redis_版本”:
案例“散列输入消息2”:
案例“散列输入消息3”:
msg.DiagnosticCnt=Convert.ToInt32(infoHash[info.Value]);
打破
//打开从info.Key获取int16的所有消息类型
案例“msg_int_message_1”:
案例“msg_int_message_2”:
msg.DiagnosticCnt=Convert.ToInt32(msgDescritionAndID[info.Key]);
打破
//剩下的一切都是从我们当前的信息中读取价值。
//默认值:
msg.DiagnosticStr=信息值;
打破
}
msgNameList.Add(msgName);
}
返回msgNameList;
}
即使infoHash包含您不感兴趣的密钥,您也可以这样编码:
private List<MessageName> createMsgObject(Dictionary<string, string> infoHash, Dictionary<string, Int16> msgDescritionAndID)
{
MessageName msgName = null;
List<MessageName> msgNameList = new List<MessageName>();
var msgObjOuter = new MessageName();
// there is no need to perform an o(1) lookup of infoHash for 40 variables.
// You already have a list of keys it contains so just enumerate them.
foreach (KeyValuePair<string, string> info in infoHash)
{
var msg = new MessageName() { MessageID = msgDescritionAndID[info.Key] };
switch (info.Key)
{
// switch all of your int16 versions first:
case "redis_version":
case "hash_int_message_2":
case "hash_int_message_3":
msg.DiagnosticCnt = Convert.ToInt32(infoHash[info.Value]);
break;
// switch on all message types getting int16 from info.Key
case "msg_int_message_1":
case "msg_int_message_2":
msg.DiagnosticCnt = Convert.ToInt32(msgDescritionAndID[info.Key]);
break;
// switch on all message types that have DiagnosticStr in info.Value;
case "msg_str_message_1":
case "msg_str_message_2":
msg.DiagnosticStr = info.Value;
break;
default: // everything left over we are not interested in
continue;
break;
}
msgNameList.Add(msgName);
}
return msgNameList;
}
private List createMsgObject(字典infoHash、字典msgDescritionAndID)
{
MessageName msgName=null;
List msgNameList=新列表();
var msgObjOuter=新消息名();
//不需要对40个变量执行infoHash的o(1)查找。
//您已经有一个包含密钥的列表,所以只需枚举它们。
foreach(infoHash中的KeyValuePair信息)
{
var msg=new MessageName(){MessageID=msgDescritionAndID[info.Key]};
开关(信息键)
{
//首先切换所有int16版本:
案例“redis_版本”:
案例“散列输入消息2”:
案例“散列输入消息3”:
msg.DiagnosticCnt=Convert.ToInt32(infoHash[info.Value]);
打破
//打开从info.Key获取int16的所有消息类型
案例“msg_int_message_1”:
案例“msg_int_message_2”:
msg.DiagnosticCnt=Convert.ToInt32(msgDescritionAndID[info.Key]);
打破
//打开所有消息类型
private List<MessageName> createMsgObject(Dictionary<string, string> infoHash, Dictionary<string, Int16> msgDescritionAndID)
{
MessageName msgName = null;
List<MessageName> msgNameList = new List<MessageName>();
var msgObjOuter = new MessageName();
// there is no need to perform an o(1) lookup of infoHash for 40 variables.
// You already have a list of keys it contains so just enumerate them.
foreach (KeyValuePair<string, string> info in infoHash)
{
var msg = new MessageName() { MessageID = msgDescritionAndID[info.Key] };
switch (info.Key)
{
// switch all of your int16 versions first:
case "redis_version":
case "hash_int_message_2":
case "hash_int_message_3":
msg.DiagnosticCnt = Convert.ToInt32(infoHash[info.Value]);
break;
// switch on all message types getting int16 from info.Key
case "msg_int_message_1":
case "msg_int_message_2":
msg.DiagnosticCnt = Convert.ToInt32(msgDescritionAndID[info.Key]);
break;
// everything left over is reading value from our current info.
// default:
msg.DiagnosticStr = info.Value;
break;
}
msgNameList.Add(msgName);
}
return msgNameList;
}
private List<MessageName> createMsgObject(Dictionary<string, string> infoHash, Dictionary<string, Int16> msgDescritionAndID)
{
MessageName msgName = null;
List<MessageName> msgNameList = new List<MessageName>();
var msgObjOuter = new MessageName();
// there is no need to perform an o(1) lookup of infoHash for 40 variables.
// You already have a list of keys it contains so just enumerate them.
foreach (KeyValuePair<string, string> info in infoHash)
{
var msg = new MessageName() { MessageID = msgDescritionAndID[info.Key] };
switch (info.Key)
{
// switch all of your int16 versions first:
case "redis_version":
case "hash_int_message_2":
case "hash_int_message_3":
msg.DiagnosticCnt = Convert.ToInt32(infoHash[info.Value]);
break;
// switch on all message types getting int16 from info.Key
case "msg_int_message_1":
case "msg_int_message_2":
msg.DiagnosticCnt = Convert.ToInt32(msgDescritionAndID[info.Key]);
break;
// switch on all message types that have DiagnosticStr in info.Value;
case "msg_str_message_1":
case "msg_str_message_2":
msg.DiagnosticStr = info.Value;
break;
default: // everything left over we are not interested in
continue;
break;
}
msgNameList.Add(msgName);
}
return msgNameList;
}