CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Jul 2011
    Posts
    6

    Shrink a whole bunch of IF statements.

    I really hate to join a forum and start asking questions, but I'm developing a program which contains a command line where you can enter commands in one window, and get the output from another (see attachment if you will). It accepts commands which I've created, and instructions from the assembly language. In total, I would expect to have somewhere around 300 commands and instructions.

    The current system I have setup is something like so:
    Code:
    public string Input = "";
    // Converts code into something readable to the interpret function.
    public void ParseInput()
    {
          // Code here would read the input offered by the text box and convert it.
          interpret();
    }
    // Reads code and decides what to do with it.
    public void Interpret();
    {
          if (input == proper_syntax)
             commandA_do();
          elseif(input == proper_syntaxB)
             commandB_do();
          // 300 elseif's later...
          else
          { // say nothing happened }
    }
    Proper syntax notwithstanding, of course. Now I would assume this is very bad to have 300 'if' long if statement (hogging resources, and clogging pipes, and whatnot). Even with the 15 or so commands I had declared using that format, it did crash the program at some times. So, what would be an effective way to condense down those if statements?
    Attached Images Attached Images

  2. #2
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,284

    Re: Shrink a whole bunch of IF statements.

    You'll need a Switch statement here

  3. #3
    Join Date
    Feb 2011
    Location
    United States
    Posts
    1,016

    Re: Shrink a whole bunch of IF statements.

    Welcome to the forum! Thanks for being so polite; we're happy to help, if we can. :-)

    A branch table comes to mind. Instead of linearly going through a long string of if's, the idea is to store the location of the handling code in hash table and then jump to the code. This way you get time complexity O(1) instead of O(n) where n is the number of types of instructions. In assembly, this was realized by storing memory address to jump to, but in C# we can do it with delegates. Declaring a delegate allows us to store references to functions that have a specific functional signature. (Sorry, they're a little complicated and I can't think of how to explain better; best to just read the MSDN article: http://msdn.microsoft.com/en-us/libr...=vs.80%29.aspx

    For example, suppose we had three instructions that take arguments like assembly code does (e.g.):
    Code:
    MOV AX, BX   //Move
    JMP AX       //Jump
    CMP AX, BX   //Compare

    Then we might write:

    Code:
    use System.Collections.Generic;
    
    //Declare the StatementHandler type to point at methods which contain a
    // functional signature wherein they return void and take only one string as input
    private delegate void StatementHandler(string);
    
    //Declare some handlers routines that will do whatever the MOV, JMP and CMP statements do
    // Notice that they all match the functional signature of a StatementHandler
    private static void movHandler(string input) { ... }
    private static void jmpHandler(string input) { ... }
    private static void cmpHandler(string input) { ... }
    
    //Declare a hash table (a type safe hash table is called a dictionary in C#
    private static Dictionary<string, StatementHandler> branchTable;
    
    //Initialize the branch table; call once at the very start of the program
    private static void initBranchTable()
    {
        //Allocate memory
        branchTable = new Dictionary<string, StatementHandler>();
        
        //Add each of the handlers to the dictionary
        branchTable.Add("mov", movHandler);
        branchTable.Add("jmp", jmpHandler);
        branchTable.Add("cmp", cmpHandler);
    }
    
    public static void interpret(string input)
    {
        //Get the part of the input before the first space (telling us what type of instruction it is; 
        //  the parsing may be slightly different based on your syntax)
        string instructionType = input.Split(' ')[0];
    
        //Check to see if we know about this type of instruction
        if( branchTable.ContainsKey(instructionType) )
        {
            //If we know this instruction, call the appropriate handler
            StatementHandler handler = branchTable[instructionType];
    
            //Call the appropriate handler routine (e.g. movHandler if it was a mov statement)
            handler(input);
    
            //N.B.: this could be more compactly written as one statement (uh, I think...):
            // branchTable[instructionType](input);
        }
        else
        {
            //This isn't an instruction
            complainToUser();
        }
    }
    Does that help? You might also want to do some benchmarking; it may or may not be faster to just use a long list of if's depending on how many branches you have exactly. (There is some small amount overhead in using delegates).

    Also, none of my code is debugged, so sorry if there are syntax errors anywhere. I just wrote it in the window...

    Hope that helps; let me know if further problems.
    Best Regards,

    BioPhysEngr
    http://blog.biophysengr.net
    --
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  4. #4
    Join Date
    Feb 2011
    Location
    United States
    Posts
    1,016

    Re: Shrink a whole bunch of IF statements.

    Quote Originally Posted by HanneSThEGreaT View Post
    You'll need a Switch statement here
    Hrm... Insightful as usual... :-)

    I wrote a lot of code without thinking too hard about switch. Apparently switch is sometimes a constant-time branch (branch table), but not always. See http://stackoverflow.com/questions/4...imitations-why

    switch might be a simpler solution that my more complicated one... not sure if there is some optimization trade off between using switch and doing it manually.

    EDIT: Eh, I thought about it some more (read the thread I linked you too) and am going to come out in favor of doing it yourself with my more complex methods. The compiled behavior of switch does not guarantee constant-time lookup (and - I am guessing - for your inputs will generate a binary search tree giving you something like O(log n) lookup time). At least if you do it yourself you know what you're getting. Use of switch still may or may not be faster depending on how many instructions you have exactly... Benchmark it, I guess, if performance is an issue.
    Last edited by BioPhysEngr; July 28th, 2011 at 01:34 AM. Reason: updated some thoughts
    Best Regards,

    BioPhysEngr
    http://blog.biophysengr.net
    --
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  5. #5
    Join Date
    Jul 2011
    Posts
    6

    Re: Shrink a whole bunch of IF statements.

    From what you've told me, a branch table does seem to be a very effective and ethical solution. I'd definitely take some time to try and implement.

    Thanks for your help and the snippet of code.

  6. #6
    Join Date
    Jul 2011
    Posts
    6

    Re: Shrink a whole bunch of IF statements.

    Eh, I can't edit my posts for whatever reason. At the current moment, I'd prefer reliability, consistency and organization versus performance. Would you know how a list of 300 functions would perform with if, switch, or a table?

  7. #7
    Join Date
    Feb 2011
    Location
    United States
    Posts
    1,016

    Re: Shrink a whole bunch of IF statements.

    Er, ethical?

    I think the tradeoff is:

    if: Good for only a few cases (< 10?)
    switch: probably reasonable performance (possibly optimal); easy to read the code
    table: most scalable, you know exactly what the code is doing

    I don't know where the regime change between when you should use if, switch and table occurs though. Probably the best advice is to rapidly prototype and get something working using switch and then if you are having performance problems implement table. Agreed, other forum members?

    I try not to get too caught up in Agile programming dogma, but rapid prototyping followed by refinement usually serves me well. I recommend it to you too.
    Best Regards,

    BioPhysEngr
    http://blog.biophysengr.net
    --
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  8. #8
    Join Date
    Mar 2004
    Location
    Prague, Czech Republic, EU
    Posts
    1,701

    Re: Shrink a whole bunch of IF statements.

    That's to solution I would use too. As benefit, it is better scalable and maintainable.
    • Make it run.
    • Make it right.
    • Make it fast.

    Don't hesitate to rate my post.

  9. #9
    Join Date
    Jul 2011
    Posts
    6

    Re: Shrink a whole bunch of IF statements.

    Alright, I think that would be the solution I would use for now. Thanks for all your help.

    (by ethical I meant logical... it was late in the night so bear with me :|)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured