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(); 
+4
source share
10 answers

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.

+10
source

Assuming when you say "querystring", you mean the parameters passed in the url, and then:

What about:

 String.Join("&", dic.Select(kv => kv.Key + "=" + kv.Value).ToArray()); 
+7
source

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.

+6
source

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.

+1
source

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).

+1
source

I would suggest that your third method has the least overhead, but it could be a close connection to your second. I don't know what Append () does under the covers or what String.Format does.

I like what your second method looks like; This is the most readable for me.

0
source

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.

0
source

3d, because it avoids formatting (which is a preprocessing of the formatted expression), and, in contrast to the first, does not use an excess delegate call

0
source

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(); 
0
source

Do not pay attention to performance, this will not be a bottleneck. Eric Smiths version is perhaps the simplest and cleanest - for this.

But remember - UrlEncode values, otherwise you will get a problem if the value contains & or whitespace or other invalid characters.

0
source

All Articles