我有以下数据:
Dictionary<string,string> dctParameters = new Dictionary(){
{"a",var1},{"b",var2},{"c",var3},....
}
我想将“dctParameters”加入查询字符串。
以下方式中最快/最好的是什么?你能想到一个更好的方法吗?
第一种方法:
StringBuilder data = new StringBuilder();
string result = dctParameters.Aggregate(data, (x, pair) => data.Append(pair.Key).Append("=").Append(pair.Value).Append("&")).ToString();
第二种方法:
StringBuilder data = new StringBuilder();
foreach (var item in dctParameters)
{
data.Append(string.Format("{0}={1}&",item.Key, item.Value));
}
string result = data.ToString();
第三种方法:
StringBuilder data = new StringBuilder();
foreach (var item in dctParameters)
{
data.Append(item.Key).Append("=").Append(item.Value).Append("&");
}
string result = data.ToString();
答案 0 :(得分:10)
如何将扩展方法作为Eric建议的变体:
public static string ToQueryString(this Dictionary<string, string> dict)
{
return '?' + string.Join("&", dict.Select(p => p.Key + '=' + p.Value).ToArray());
}
例如:
dctParameters.ToQueryString();
考虑到这种过程不太可能使服务器陷入困境,任何实现的性能成本都不值得失眠。问题是(正如你所说的)更好而不是更快而你所看到的是一种优雅的方法,而不是最少的CPU周期。
答案 1 :(得分:7)
假设当你说“querystring”时,你指的是在URL中传递的参数,那么:
怎么样:
String.Join("&", dic.Select(kv => kv.Key + "=" + kv.Value).ToArray());
答案 2 :(得分:6)
老实说,在我看来,你正试图过早地进行优化。
我不相信这些之间存在显着差异,但您可以使用计时器对它们进行基准测试。因此,我建议选择一个您认为对于可能需要维护代码的开发人员最具可读性的那个。
答案 3 :(得分:1)
这三种方法都不正确!最后你会得到一个虚假的&符号。它不会影响浏览器,但它只是糟糕的形式。
肯定不会涉及string.Format
,因为这需要通过格式字符串进行解析。我个人会使用第三种方法并预先计算总结束字符串长度以提供给StringBuilder
构造函数。即使它大致是正确的大小或只是猜测,然后你不能重新分配StringBuilder
的内存。为词典中的每个项目YMMV尝试20次。
其他人已经并将讨论过早优化,但string.Format
的使用完全没有必要,在这种情况下更不用说错误了。
答案 4 :(得分:1)
我从根本上同意Russ。选择最具可读性并将其纳入方法中。如果遇到性能问题,您可以随时更改实施。
作为旁注,通过选择另一个类来保存数据可能会获得更多性能,因为枚举非常昂贵。考虑ListDictionary甚至KeyedCollection(这需要自定义Parameter
类或结构。)
答案 5 :(得分:0)
我猜你的第三种方法开销最小,但它可能与你的第二种方法紧密相关。我不知道Append()在幕后做什么或者String.Format正在做什么。
我喜欢你的第二种方法;这对我来说是最具可读性的。
答案 6 :(得分:0)
在这种情况下,Best是一个非常相对的术语,因为它们都能满足您的需求。就速度而言,我认为在这里和那里担心几毫秒是不值得的。这些集合永远不会大到足以让您看到任何明显的性能差异。
首先做的是什么(不破坏好的设计),然后担心在需要时进行优化。
答案 7 :(得分:0)
3d因为它避免格式化(这是格式表达式的预处理)而且与1st相反不使用委托的冗余调用
答案 8 :(得分:0)
如果你真的需要最好的性能(这似乎是过早的优化),我认为你应该首先计算字符串的大小,然后创建一个具有该容量的字符串构建器。这将使字符串生成器不再重新分配,并且还将导致字符串中没有任何未使用的空间:
int len = -1;
foreach (var item in dctParameters) {
len += item.Key.Length + item.Value.Length + 2;
}
StringBuilder data = new StringBuilder(len);
foreach (var item in dctParameters) {
if (data.Length > 0) data.Append('&');
data.Append(item.Key).Append('=').Append(item.Value);
}
string result = data.ToString();
答案 9 :(得分:0)
没关系性能,这不会成为瓶颈。埃里克史密斯的版本似乎是最简单和最干净的 - 去吧。
但请记住至UrlEncode
值,否则如果值恰好包含&
或空格或其他非法字符,则会出现问题。