Is it expensive to create objects?
Creating a new object is very cheap. You'd have to create a lot of objects in a very tight loop to notice any difference... but at the same time, it's not free. You also need to bear in mind that the costs are half hidden - you have some cost upfront when you create the object, but also it means the garbage collector has more work to do.
So is a cleaner design worth the performance hit? We can't tell you that - it depends on how your code is used. I strongly suspect the performance hit will be insignificant, but if you are using this in a tight loop, it may not be. There's only one way to find out though: measure it if you're concerned. Personally I'd probably just go for the cleaner design and only check the performance when it looked like it was becoming a problem.
(If this method is hitting disk or a database, by the way, the difference is almost bound to be insignificant.)
One suggestion, by the way: does your HistoryEntry
type actually need to be mutable? Could you make all the properties read-only, backed by private read-only variables?
Just to mention Will's point - I somewhat agree with him. If these two methods are the only places you need this concept, I'm not at all sure it's worth creating a new type for the sake of it. Not because of the performance aspect, but just because you're introducing an extra bunch of code for no demonstrated benefit. The key word here is demonstrated - if you're actually using the same collection of parameters in other places, or could usefully put logic into the HistoryEntry
class, that's a different matter entirely.
EDIT: Just to respond to the point about multiple integer arguments - C# 4 will allow named arguments which should make this easier. So you could call:
AddHistoryEntry(userId: 1, companyId: 10);
Making the names visible with an additional class needs one of:
- Named constructor arguments from C# 4 (in which case you're no better off than with the method)
- Mutable types (urgh - that could lead to hard to trace bugs which wouldn't have been in the original version)
- Long static method names to construct instances ("FromUserAndCompanyId") which become unwieldy with more parameters
- A mutable builder type
- A bunch of "With" methods:
new HistoryEntry().WithCompanyId(...).WithUserId(...)
- this makes it harder to validate at compile-time that you've provided all the required values.
He might be correct if you have millions of these objects in memory simultaneously. But if you don't, then he's bringing up what is almost certainly a moot point. Always choose a better design first, and then modify it only if you're not meeting performance requirements.