Is effect.Parameters[""].SetValue() still slower than keeping a reference to the EffectParameter?

Would like to get a reality check.

Common knowledge/superstition in the old Xna days was that this:

//in Draw
effect.Parameters["myParameter"].SetValue(x)

… was slower than this:

//in fields
private EffectParameter myParameter;

//in LoadContent
myParameter = effect.Parameters["myParameter"];

//in Draw
myParameter.SetValue(x);

(source).

We were always encouraged to store the local reference and call SetValue on it. I remember seeing exactly this pattern in the official samples.

Looking at Monogame’s source code though…

		public EffectParameter this[string name]
        {
            get
            {
                int index;
                if (_indexLookup.TryGetValue(name, out index))
                    return _parameters[index];
                return null;
			}
        }

It’s a string lookup into a Dictionary<string, int>, followed by indexing into an effect parameter array. Which sounds pretty dang fast to me.

Retrieving a value by using its key is very fast, close to O(1), because the Dictionary class is implemented as a hash table.

Given that I always found storing a local reference hideous and painful, I’m inclined to never do so again. Seems to me if you’re setting enough effect parameters each frame for the performance impact to be anything more than completely negligible, you’ve got other problems.

Am I correct?

It’s not really “slow” - but it’s still slower than keeping a reference. And you do it 60 times per second per parameter per effect - so it can add up to quite some wasted cycles which could be used better somewhere else. Especially for games, performance is always a premium.

Of course, if your game is not demanding on the hardware every optimization is debatable. But look at it like this: If your game uses up less cycles it also uses up less power, which may be interesting for mobile applications :slight_smile:

Okay, I guess I can see the argument on mobile devices where you’ve got a lot less total cycles to work with and you’re probably looking for any advantage you can get.

But fairly high up on my list of rules is this: premature optimization is the root of all evil. Sure, you save one cycle on the string lookup, but if the overhead on the subsequent draw call costs you a thousand cycles, who is going to notice? All you’ve done is spend more time jumping about your class to add and initialize the local variable, and now your code is more confusing and harder to read.

So I think my take on it is, if .SetValue() ever shows up in my performance profiler or if I’m desperate to squeeze out that extra 0.1%, I’ll consider optimizing it then. Otherwise, nah.

I don’t find the code harder to read with that specific optimization - it’s just like 3 lines more code to type.

And as said, in complex games those really add up (profiler wont even notice because it’s too scattered troughout the code) - and I clearly do not want basically a full array lookup for every frame for every shader and multiple drawcalls with no benefit gaining from it.

But in the end I am just refering to your original question if it is still slower - yes it is. Is it considerably slower? Probably not - it’s like a car with a dirty air filter is still going to drive. It just drives a little worse. Doesn’t matter in daily traffic, but may make the difference in a race :wink:

Agree to disagree then. To me, it’s 3 lines per parameter split across three locations in the file, which adds a bunch of scrolling up and down as well as unnecessary bloat to your fields and LoadContent method.

This confuses me, though:

(profiler wont even notice because it’s too scattered troughout the code)

Are you not using the “Functions” or “Modules” views? It collates routines that are called from a variety of different places in your code. I’d need to verify whether indexing routines show up in it, but other non-method syntactic sugar like getters and setters certainly do.