سؤال

Suppose I call Print very often in my code.

Do I have to declare CurrentPosition as global or local variable?

I want to know which version is faster.

Option A:

    int CurrentPosition = 0;
    void Print(string key, int conc, int col, byte _color) {
        if (col <= cMax ? col >= cMin : false) {
            if (CurrentRows.TryGetValue(key + "#" + conc.ToString(), out CurrentPosition)) { //Row is in the vieport
                grid.GetCell(CurrentPosition, col).Presenter.Background = new SolidColorBrush(Color.FromRgb(255, 255, 0));
            }
        }
    }

Option B:

    void Print(string key, int conc, int col, byte _color) {
    int CurrentPosition = 0;
        if (col <= cMax ? col >= cMin : false) {
            if (CurrentRows.TryGetValue(key + "#" + conc.ToString(), out CurrentPosition)) { //Row is in the vieport
                grid.GetCell(CurrentPosition, col).Presenter.Background = new SolidColorBrush(Color.FromRgb(255, 255, 0));
            }
        }
    }
هل كانت مفيدة؟

المحلول

I propose to have a look under the hood to know how the C# compiler deals with these two options.

Let's say I have this simplistic class:

class Test
{
    private int _currentPosition;

    public int OptionA()
    {
        ImplOutParameter(out _currentPosition);
        return _currentPosition;
    }

    public int OptionB()
    {
        int currentPosition;
        ImplOutParameter(out currentPosition);

        return currentPosition;
    }

    public void ImplOutParameter(out int position)
    {
        position = 1;
    }
}

The two first methods are very similar to yours. The third one is here to test the out parameter implementation.

Let's compile this class in Release configuration. Using your favorite IL viewer, the method OptionA looks like:

Method OptionA

It pushes the reference of the object on the stack twice to get the variable member reference and to call the ImplOutParameter method. Then it returns the value of the variable member.

The method OptionB looks like:

Method OptionB

It pushes the reference of the object on the stack, pushes the address of the variable on the stack and call the ImplOutParameter method.Then it returns the value. It doesn't need to take time in order to allocate the variable.

Based on this analysis, I tend to say the OptionB implementation is a bit faster than the first one, but hey, this is very small. :)

نصائح أخرى

If you're maintaining the state of CurrentPosition between calls and you're not passing the value into the method, then it needs to be outside. Otherwise, it starts fresh every time.

The best policy would be a third option of passing CurrentPosition into the method as a parameter, however, and maintain the state independent of the routine's code.

In terms of speed, allocation does take a small amount of time, but it's generally negligible. The "stack frame" will be lengthened regardless, and assigning a default value takes about as long as an assignment.

So, the most you'll save is a couple of cycles per call (i.e., nanonseconds), but yes, declaring it outside is going to be a hair faster.

If you want to know which is faster, test it. That's the only way to really be sure.

Always test performance if you're making a decision on what method to choose based on it. If it isn't worth testing, then you don't need the extra cycles.

That being said, the two methods are [i]functionally[/i] different, so your decision shouldn't be based on their speed. Option B sets CurrentPosition each time Print is called, whereas Option A sets CurrentPosition to 0 once and its value when Print is called is [i]not guaranteed to be 0[/i] so you should choose whichever option provides the correct function.

I can tell you that the speed different will likely be negligible, practically non-existent between the two.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top