I am making a XNA game and I am calling following code 2 to 20 times per update. I tried googling and it seems like this is semi-slow, so I just thought I'd ask if there is any faster way to compare types?
Code:
public Modifier this[Type type]
{
get
{
for (int i = 0; i < this.Count; i++)
{
if (this[i].GetType() == type)
{
return this[i];
}
}
throw new NotImplementedException("Fix this");
}
set
{
for (int i = 0; i < this.Count; i++)
{
if (this[i].GetType() == type)
{
this[i] = value;
}
}
if(System.Diagnostics.Debugger.IsAttached)
System.Diagnostics.Debugger.Break();
}
}
This code is in ModifierCollection class which inherits from a List. Modifier is a part of particle engine. Also, my game isnt in condition where I can actually test this yet so I cant test this, but this should work right?
I read something about RunTimeTypeHandles which should be faster, should I use it?
EDIT: What I am aiming to do with this is that I can do the following:
(particleEffect["NameOfEmitter"].Modifiers[typeof(SomeCoolModifier)] as SomeCoolModifier).Variable = Value;
Basically I just want to change the value of some Modifiers in runtime.
EDIT 2: I just realized that I can just save the reference of Modifier to the class where I am at the moment calling this :P Maybe not as clean code if I have 5-10 modifiers but should remove this problem.
If you don't need any of the extra functionality exposed by Type, and you're only concerned with absolute equality between types--i.e., you don't need to support inheritance--RuntimeTypeHandle is the fastest way to do this comparison.
Really, though, I would question whether this isn't a weakness of your class design. Unless you have a compelling reason to check the type directly, it's probably better to expose some sort of value (probably an enum) on your objects that represents what they are, and do your comparisons against that.
If you want to be really fast and can trust the code that is calling you, change the indexer to just take an int. Then in whatever method (which you didn't show) that callers use to add Types to the list, return back to them the corresponding int. It's a worse API but it means you don't have to do any loops or lookups.
You could store the values in a dictionary indexed by type rather than a list so you wouldn't have to do an O(n) iteration over the list each time.
As noted in the comments, this does depend on the size of n and may be a micro-optimization. I'd recommend profiling your application.
Related
I keep seeing examples online, where there is a property of an element within a method that is copied to a local variable before use. For example, something like this (from Microsoft's StackPanel source code):
UIElementCollection children = arrangeElement.InternalChildren;
...
for (int i = 0, count = children.Count; i < count; ++i)
{
UIElement child = (UIElement)children[i];
if (child == null) { continue; }
...
}
Can anyone explain to me what the benefit of doing that is (if there is one), rather than accessing the property directly each time, like this?:
for (int i = 0, count = arrangeElement.InternalChildren.Count; i < count; ++i)
{
UIElement child = (UIElement)arrangeElement.InternalChildren[i];
if (child == null) { continue; }
...
}
Clearly, it saves a few characters on the screen, but that's not much of a reason to do this. Also, I understand why we might want to do this with a long running method, as a form of caching:
double value = GetValueFromLongRunningMethod();
...
for (int i = 0; i < someCollection.Count; i++) DoSomethingWith(value);
But I see this done with properties a lot and wonder why. Here's another commonly found example from the internet to do with virtualization:
IItemContainerGenerator generator = this.ItemContainerGenerator;
GeneratorPosition position = generator.GeneratorPositionFromIndex(firstVisibleItemIndex);
Why do that instead of this?:
GeneratorPosition position =
this.ItemContainerGenerator.GeneratorPositionFromIndex(firstVisibleItemIndex);
Finally, if this is done for the same reason that we might cache the result of a long running method, then how are we supposed to know which properties need to be accessed in this way?
Firstly, it avoids calling .InternalChildren lots of times. This could be a small but noticeable reduction of virtual calls (since it is used in a loop), but in some cases it might be much more significant. In some cases, a property that returns a collection or array might allocate every time it is called; DataRow.ItemArray is a classic example of this - so it is actively harmful to call it each time. An additional consideration is that even if it returns the same array each time it is called, there is JIT magic that happens to elide bounds checking, but it'll only work if the JIT can see that you are iterating a single array for the entire duration. If you stick a property accessor in the middle: this won't be obvious and the bounds check removal won't happen. It also might not happen if you've manually hoisted the upper bound!
Side note: if it isn't an array, then foreach would probably usually be preferable, and there would not be any advantage to introducing a local, due to how foreach works internally.
Note: since you're using .Count vs .Length, this definitely isn't an array, and you should probably simplify to:
foreach(UIElement child = in arrangeElement.InternalChildren) {...}
or
foreach(var child = in arrangeElement.InternalChildren) {...}
Not only does this remove this question completely, but it means that the type's own iterator (which might be an optimized struct iterator, or might be a simple IEnumerable<T> class, such as a compiler-generated iterator block) can be used. This usually has more direct access to the internals, and thus bypasses a few indirections and API checks that indexers require.
It might be fruitful in some cases like when you have to
debug some piece of code and you need to instantly see the value of variable
do a few operations at a time with an object, which requires casting - as result you cast it once
and sometimes, when you use value type objects this kind of making a local copy gives you an opportunity to not change the value of class' property
Why do that instead of this?:
GeneratorPosition position =
this.ItemContainerGenerator.GeneratorPositionFromIndex(firstVisibleItemIndex);
Let's get very abstract about this:
We get a generator. That apparently is this.ItemContainerGenerator for now, but that could change.
We use it. Only once here, but usually in multiple statements.
When we later decide to get that generator elsewhere, the usage should stay the same.
The example is too small to make this convincing, but there is some kind of logic to be discerned here.
I have a function which will be called thousands of times per day, and I want to optimize this function so it will be as fast and efficient as possible.
In this function, a list will be checked and based on the result of this check, different actions will happen. My question is what is the most efficient way of determining how many elements are in this list.
Obviously, you can just check like this:
List<Objects> data = GetData();
if (data.Count == 0)
{
//Do something
}
else if (data.Count < 5)
{
//Do something with a small list
}
else
{
//Do something with a larger list
}
Is this already the fastest/most efficient way of doing this?
I came up with an alternative, but I would like some suggestions
List<Objects> data = GetData();
int amountOfObjects = data.Count();
if (amountOfObjects == 0)
{
//Do something
}
else if (amountOfObjects < 5)
{
//Do something with a small list
}
else
{
//Do something with a larger list
}
You should use the property Count as it is a pre-calculated value and will not require recalculating the value when you use it, whereas the method Count() will try to be a smart ass and try to work out if it needs to recount or not, but that working out alone is still more effort than just using Count.
So just use what you have initially done.
For List<T>, the Count property really just returns a field because the implementation is an array list that needs to know very precisely how many elements are in this collection. Therefore, you won't gain any performance by trying to cache this value or anything alike. This is just no problem.
This situation may be different when you use other collection implementations. For example, a LinkedList conceptually has no clue of how many elements are in it, but has to count them, which is an expensive operation.
Edit: Your alternative using Count() is actually a very bad thing. Since List<T> is sealed, the compiler will create a static method call for accessing the Count property meanwhile Count() results in a cast and a virtual method call over an interface. That makes up much more cost and the JIT-compiler can do less magic such as inlining.
I have seen this in many places in the .NET framework. Unfortunately, I can't remember the others but they are all in the Katana source code assemblies.
Stuff is put into a tuple and immediately removed / read back out in the same method. This doesn't make any sense to me.
I understand (and also from reading the Wikipedia entry on the subject and having learnt the meaning when studying relational data many years ago) its uses. Just that this particular behavior does not make much sense to me.
public AuthenticationResponseChallenge AuthenticationResponseChallenge
{
get
{
Tuple<string[], IDictionary<string, string>> challengeEntry = this.ChallengeEntry;
if (challengeEntry == null)
{
return null;
}
return new AuthenticationResponseChallenge(challengeEntry.Item1, new AuthenticationProperties(challengeEntry.Item2));
}
set
{
if (value == null)
{
this.ChallengeEntry = null;
return;
}
this.ChallengeEntry = Tuple.Create<string[], IDictionary<string, string>>(value.AuthenticationTypes, value.Properties.Dictionary);
}
}
UPDATE
Okay, sorry, bad example. I've been working too long. I need to an example that illustrates my point. Unfortunately, I've rummaged through so much since morning that I can't remember and will get back to this when I can.
In that way, the original tuple this.ChallengeEntry, isn't changed when the set / returned tuple changes.
Along the way, it keeps references to the original items in the tuple, but not the tuple itself.
In the example you provided, you have two properties that work together: AuthenticationResponseChallenge and ChallengeEntry. They can both be accessed at any time, but the values need to be analogous.
The AuthenticationResponseChallenge is calculated from the ChallengeEntry.
I can't answer for why the authors of any library make the design decisions that they do. I can say that the built in Tuple is convenient for temporary storage when you need any number of values associated together and you don't need the semantics of a dictionary.
In this particular instance, I personally would have done one of two things:
Create my own struct/object with meaningful names for the member elements and a ToAuthenticationResponseChallenge() conversion method and a constructor that accepts an AuthenticationResponseChallenge object.
Create an extension method or function that does the conversion.
I am a C#-Newbie.
I have a function that is supposed to return all values from a List, that have the matching time-stamp:
static public PointCloud getPointsByTime (float time)
{
PointCloud returnList = new List<PointData> ();
for (int i = 0; i < _pointCloud.Count; i++) {
if (_pointCloud [i].time == time) {
returnList.Add (_pointCloud [i]);
}
}
return returnList;
}
Where
public class PointData
{
public float time;
// and some other members
}
and
// let's call a list of PointData-objects a PointCloud
using PointCloud = System.Collections.Generic.List<PointData>;
Does my function do what I want it to do? Or do I have to create a new PointData-object? Am I able to use my returned PointCloud or will it be out of scope and deleted?
This may be not the best example to explain so feel free to link me to something better. I think you get what my basic quastions are.
As #Patrick suggested inheriting for List seems more reasonable, but I would go further and I would just use a List so you don't create an unnecessary class if it is not going to add anything extra.
Also I suggest you to have a look to LINQ which makes the code more readable and is a very powerful feature that you would like to master as soon as possible. :)
Your method could look then like this:
_pointCloud.Where(p => p.time == time).ToList();
Also try to get familiar with properties:
public class PointData
{
public float Time { get; set; }
}
And you may want to follow the more standard C# coding style (although this is completely personal) of using PascalCase for public members instead of camelCase.
Your code is correct. You can use your function like so:
var someTime = 0.0f;
var pointsAtTime = getPointsByTime(someTime);
DoSomethingWith(pointsAtTime);
The return value from the function remains in scope if you assign it to some local variable (e.g. pointsAtTime here).
EDIT: As Peter Schneider correctly notes in the comments, you need to be aware that this function creates a new list with references to the matching points, and does not create new points. This might or might not be what you want.
However, if you're new to C#, here are some things you might want to keep in mind:
Methods in C# are conventionally named in TitleCase, e.g. GetPointsByTime and not getPointsByTime.
Assigning names to generic types like using PointCloud = List<PointData>, while technically allowed, is not very idiomatic and might confuse other readers of your code. If you think a list of PointData is special enough to have its own type, create a type for it (either by inheriting from List<PointData> or, preferably, using a IList<PointData> as a member in a new PointCloud class). Or just use using System.Collections.Generic and use List<PointData> throughout your code, which is what most people would do.
Comparing floating-point numbers for equality is sometimes discouraged as this might fail in some cases due to representation errors; if the time is truly a continuous value, you might want to look for points in a specific time period (e.g. points who fall within some range around your desired time). You don't really have to worry about this for now, though.
According to [MSDN: Array usage guidelines](http://msdn.microsoft.com/en-us/library/k2604h5s(VS.71).aspx):
Array Valued Properties
You should use collections to avoid code inefficiencies. In the following code example, each call to the myObj property creates a copy of the array. As a result, 2n+1 copies of the array will be created in the following loop.
[Visual Basic]
Dim i As Integer
For i = 0 To obj.myObj.Count - 1
DoSomething(obj.myObj(i))
Next i
[C#]
for (int i = 0; i < obj.myObj.Count; i++)
DoSomething(obj.myObj[i]);
Other than the change from myObj[] to ICollection myObj, what else would you recommend? Just realized that my current app is leaking memory :(
Thanks;
EDIT: Would forcing C# to pass references w/ ref (safety aside) improve performance and/or memory usage?
No, it isn't leaking memory - it is just making the garbage collector work harder than it might. Actually, the MSDN article is slightly misleading: if the property created a new collection every time it was called, it would be just as bad (memory wise) as with an array. Perhaps worse, due to the usual over-sizing of most collection implementations.
If you know a method/property does work, you can always minimise the number of calls:
var arr = obj.myObj; // var since I don't know the type!
for (int i = 0; i < arr.Length; i++) {
DoSomething(arr[i]);
}
or even easier, use foreach:
foreach(var value in obj.myObj) {
DoSomething(value);
}
Both approaches only call the property once. The second is clearer IMO.
Other thoughts; name it a method! i.e. obj.SomeMethod() - this sets expectation that it does work, and avoids the undesirable obj.Foo != obj.Foo (which would be the case for arrays).
Finally, Eric Lippert has a good article on this subject.
Just as a hint for those who haven't use the ReadOnlyCollection mentioned in some of the answers:
[C#]
class XY
{
private X[] array;
public ReadOnlyCollection<X> myObj
{
get
{
return Array.AsReadOnly(array);
}
}
}
Hope this might help.
Whenever I have properties that are costly (like recreating a collection on call) I either document the property, stating that each call incurs a cost, or I cache the value as a private field. Property getters that are costly, should be written as methods.
Generally, I try to expose collections as IEnumerable rather than arrays, forcing the consumer to use foreach (or an enumerator).
It will not make copies of the array unless you make it do so. However, simply passing the reference to an array privately owned by an object has some nasty side-effects. Whoever receives the reference is basically free to do whatever he likes with the array, including altering the contents in ways that cannot be controlled by its owner.
One way of preventing unauthorized meddling with the array is to return a copy of the contents. Another (slightly better) is to return a read-only collection.
Still, before doing any of these things you should ask yourself if you are about to give away too much information. In some cases (actually, quite often) it is even better to keep the array private and instead let provide methods that operate on the object owning it.
myobj will not create new item unless you explicitly create one. so to make better memory usage I recommend to use private collection (List or any) and expose indexer which will return the specified value from the private collection