Which of these code samples has the best performance?

Answering one of my questions, I got a series of answers stating that style 2 can work better than style 1. I don’t understand how, because I believe that they should emit essentially the same machine instructions ( if they are written in C ++). Could you explain why style 2 might work better?

I rewrote two styles here to simplify the link:

Style 1:

while (!String.IsNullOrEmpty(msg = reader.readMsg()))
{
    RaiseMessageReceived();
    if (parseMsg)
    {
        ParsedMsg parsedMsg = parser.parseMsg(msg);
        RaiseMessageParsed();
        if (processMsg)
        {
            process(parsedMsg);
            RaiseMessageProcessed();
        }
    }
}

Style 2:

while (!String.IsNullOrEmpty(msg = reader.readMsg()))
{
    RaiseMessageReceived();
    if (!parseMsg) continue;

    ParsedMsg parsedMsg = parser.parseMsg(msg);
    RaiseMessageParsed();
    if (!processMsg) continue;

    process(parsedMsg);
    RaiseMessageProcessed();
}
+3
source share
6 answers

I had to check it out.

Here is my version of the code:

using System;
using System.Collections.Generic;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Tester t=new Tester();
            t.Method1(new Stack<string>(), new MsgParser(), true, true);
            t.Method2(new Stack<string>(), new MsgParser(), true, true);
        }
    }
    class Tester
    {
        public void Method1(Stack<string> strings, MsgParser parser, bool parseMsg, bool processMsg)
        {
            string msg;
            while (!String.IsNullOrEmpty(msg = strings.Pop()))
            {
                RaiseMessageReceived();
                if (parseMsg)
                {
                    ParsedMsg parsedMsg = parser.ParseMsg(msg);
                    RaiseMessageParsed();
                    if (processMsg)
                    {
                        process(parsedMsg);
                        RaiseMessageProcessed();
                    }
                }
            }
        }

        public void Method2(Stack<string> strings, MsgParser parser, bool parseMsg, bool processMsg)
        {
            string msg;
            while (!String.IsNullOrEmpty(msg = strings.Pop()))
            {
                RaiseMessageReceived();
                if (!parseMsg) continue;

                ParsedMsg parsedMsg = parser.ParseMsg(msg);
                RaiseMessageParsed();
                if (!processMsg) continue;

                process(parsedMsg);
                RaiseMessageProcessed();
            }

        }

        private void RaiseMessageProcessed()
        {
            Console.WriteLine("Done");
        }

        private void process(ParsedMsg msg)
        {
            Console.WriteLine(msg);
        }

        private void RaiseMessageParsed()
        {
            Console.WriteLine("Message parsed");
        }

        private void RaiseMessageReceived()
        {
            Console.WriteLine("Message received.");
        }
    }

    internal class ParsedMsg
    {
    }

    internal class MsgParser
    {
        public ParsedMsg ParseMsg(string msg)
        {
            return new ParsedMsg();
        }
    }
}

( ) Reflector. , :

internal class Tester
{
    // Methods
    public void Method1(Stack<string> strings, MsgParser parser, bool parseMsg, bool processMsg)
    {
        string msg;
        while (!string.IsNullOrEmpty(msg = strings.Pop()))
        {
            this.RaiseMessageReceived();
            if (parseMsg)
            {
                ParsedMsg parsedMsg = parser.ParseMsg(msg);
                this.RaiseMessageParsed();
                if (processMsg)
                {
                    this.process(parsedMsg);
                    this.RaiseMessageProcessed();
                }
            }
        }
    }

    public void Method2(Stack<string> strings, MsgParser parser, bool parseMsg, bool processMsg)
    {
        string msg;
        while (!string.IsNullOrEmpty(msg = strings.Pop()))
        {
            this.RaiseMessageReceived();
            if (parseMsg)
            {
                ParsedMsg parsedMsg = parser.ParseMsg(msg);
                this.RaiseMessageParsed();
                if (processMsg)
                {
                    this.process(parsedMsg);
                    this.RaiseMessageProcessed();
                }
            }
        }
    }

    private void process(ParsedMsg msg)
    {
        Console.WriteLine(msg);
    }

    private void RaiseMessageParsed()
    {
        Console.WriteLine("Message parsed");
    }

    private void RaiseMessageProcessed()
    {
        Console.WriteLine("Done");
    }

    private void RaiseMessageReceived()
    {
        Console.WriteLine("Message received.");
    }
}
+4

, , . .

- .

1 , ( ) ( ), , . ( ). , , .

+9

- -/​​ . , , JIT . , .

, 2 , 1 , , if , .

, , .

+3

, , , ... .

0

Why not take a sheet from Jeff's book and time for both code snippets, for example, in this question ?

0
source

The code stream looks identical, and the bytecode must be the same.

Disclaimer: I'm a C / C ++ programmer, I really don't do C #

0
source

All Articles