What is the fastest way to join the <string, string> dictionary in querystring?
I have the following data:
Dictionary<string,string> dctParameters = new Dictionary(){ {"a",var1},{"b",var2},{"c",var3},.... } I want to join the "dctParameters" in querystring.
What is the fastest / best of the following methods? Can you imagine the best way to do this?
1st method:
StringBuilder data = new StringBuilder(); string result = dctParameters.Aggregate(data, (x, pair) => data.Append(pair.Key).Append("=").Append(pair.Value).Append("&")).ToString(); Second method:
StringBuilder data = new StringBuilder(); foreach (var item in dctParameters) { data.Append(string.Format("{0}={1}&",item.Key, item.Value)); } string result = data.ToString(); Third method:
StringBuilder data = new StringBuilder(); foreach (var item in dctParameters) { data.Append(item.Key).Append("=").Append(item.Value).Append("&"); } string result = data.ToString(); What about the extension method as a variation of Eric's sentence:
public static string ToQueryString(this Dictionary<string, string> dict) { return '?' + string.Join("&", dict.Select(p => p.Key + '=' + p.Value).ToArray()); } eg:
dctParameters.ToQueryString(); The cost of executing any of your implementations is really not worth losing a dream, considering that such a process is unlikely to lead to a loss of the server. The problem is that (as you say) is better not faster, but what you think is an elegant approach, not the minimum processor cycles.
Honestly, it seems to me that you are trying to prematurely optimize.
I do not believe that there will be a significant difference between them, but you can compare them using timers. Therefore, I would suggest choosing one that, in your opinion, will be the most readable for other developers who may need to support the code.
All three methods are wrong! You will get a fake ampersand at the very end. This will not affect the browser, but it is just a bad form.
Of course, this is not the one that includes string.Format , because it requires parsing a string in a format. I personally would go with the third method and pre-calculate the length of the final string to feed into the StringBuilder constructor. Even if it's roughly the right size or just guessed, you are not reallocating the memory for StringBuilder . Try something like 20 for each item in your dictionary, YMMV.
Others talked and talked about premature optimization, but using string.Format completely unnecessary, not to mention incorrect in this case.
I fundamentally agree with Russ . Choose the most read and consider them in the method. You can always change your implementation if you have any performance issues.
As a side note, you are likely to get more performance by choosing a different class to store your data as listing is quite expensive. Think of a ListDictionary or even a KeyedCollection (which would require a custom class or Parameter structure).
Best is a pretty relative term in this case, since they all do what you want. As for speed, I donβt think it is worth the effort to worry for a few milliseconds here and there. These collections will never be large enough for you to see noticeable differences in performance.
Do what works first (without prejudice to good design), and then worry about optimizations when you need to.
If you really need better performance (which seems like premature optimization), I think you should first calculate the row size and then create a row builder with that capacity. This will cause the row builder to be redistributed, and also lead to the creation of the row without any unused space:
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();