I'm working on a webservice and I'm returning JSON. However, I'm returning a List<KeyValuePair<string, int>>
, since that's all I'm really ever going to be dealing with (property => value)
Now sometimes I myself will be calling these functions to aggregate the results, so I end up with something like
List<KeyValuePair<string, int>> myList = resultList.where(o => o.Key =="StringKEY");
and sometimes
List<KeyValuePair<string, int>> myList = resultList.sum(o => o.Key =="StringKEY");
My question is, would it be more efficient to do the following (custom class vs dictionary):
List<MyObject> myObj = resultObjList.where(o => o.Property1 == "stringProperty")
and so on.
Is there any benefit to using custom objects? I will not ever need to be adding properties, and in this case I can say there will never be a need for additional properties.
-
1You might be interested in this question: When should I use a 2-property class over a pre-built structure like a KeyValuePair?Rachel– Rachel2012年01月24日 18:45:25 +00:00Commented Jan 24, 2012 at 18:45
3 Answers 3
You're asking what is the difference between a KeyValuePair
and a two-property object? There is none, KeyValuePair
is a two-property object. Actually, there might be a difference: KeyValuePair
is a value type and your custom object will probably be a reference type. The difference between a reference type and value type can have an impact on the performance (especially in some specific environments, like XNA on XBox). But if this difference is important for you, you can always make your custom type into a value type.
So, my advice is to use KeyValuePair
for things that actually are a key and a value. If the relation between the two values is different, you should create your custom type, for readability sake.
Another option in C# 7.0 and newer is to use tuples. They're value types, just like KeyValuePar
, but using them does not imply you have a key and a value.
-
thanks for that answer.. since the application is for a webservice and response times are crucial to providing good service, i need the optimum solution, which you've provided.. thank you!hanzolo– hanzolo2012年01月24日 21:12:22 +00:00Commented Jan 24, 2012 at 21:12
-
2@hanzolo, if response times are crucial, you should base your decisions on profiling your code, not something someone on the internet said.svick– svick2012年01月24日 21:15:23 +00:00Commented Jan 24, 2012 at 21:15
-
but i snopes'd it! ;-)hanzolo– hanzolo2012年01月24日 22:20:35 +00:00Commented Jan 24, 2012 at 22:20
Profiling whenever in doubt is definitely a good way to go. Since I can't profile your code (nor would I probably want to), I'll share my two cents of theory:
Both two-property object and your KeyValuePair essentially store exactly the same data and in both instances you are storing your data in a List collection which means that in order to find individual entries, you have to perform a full collection scan, O(n) operation.
Theoretically, KeyValuePair<> might be tad faster (not sure if even profiler would notice it) because there's one less level of indirection that has to take place.
- ListEntry(KeyValuePair) --> string; ListEntry(KeyValuePair)
- ListEntry(obj ref) --> Object --> string; ListEntry(obj ref) --> Object(int)
However, one change that you could do to improve performance if your collection gets rather large, is use a different type instead of a List. With List you are stuck with linear searches and can't really get away from that (unless you'll spend extra effort manually sorting it, but why would you).
Since you have a notion that each object has a key, use Dictionary<> or SortedDictionary<> which would be keyed of your key.
In this case, just to give you a comparison, if your List has 1000 entries and you need to find one, worst case will require you to do 1000 compares. If you use a keyed collection, in worst case, you will only perform 10 compares. When performing a sum or looking for multiple items with same key, they will all be located together in the collection, so it also becomes much easier (computationally) to do that operation, rather than searching for them everywhere.
I think you'll be hard pressed to find any real-world performance difference given this is a web service -- the fastest HTTP request will still be orders of magnitude slower than any sort of micro-optimization you can get here.
Code-wise, unless I am actually dealing with an arbitrary list of keys, I'd run with a good old fashioned POCO. Intellisense and compile-type checking are cool.
-
2in terms of HTTP request round-trip time, you are correct. timing difference by this optimization is negligible because of network overhead on top of it. But what about 5,000 requests hitting the webserver? If you reduce CPU requirements of your algorithms, you may not improve single-request response time, but you could increase rate of requests serviced. Then again, what's the realistic request rate for a typical web page.DXM– DXM2012年01月25日 19:16:49 +00:00Commented Jan 25, 2012 at 19:16