-------------- Original message ----------------------
From: Glenn Linderman <[EMAIL PROTECTED]>
> On approximately 10/14/2005 6:25 AM, came the following characters from 
> the keyboard of [EMAIL PROTECTED]:
> > Apart from personal involvement, I am a believer that where you can
> > speed an application you should. The sum of all very small
> > inefficiencies can lead to a large speed problem.
> 
<snip>
> 
> Hmm. I'm not quite sure how one searches an array of functions for a 
> parameter of arg -- perhaps I'm missing something in this explanation, 
> but it sounds intriguing enough for me to comment, and hope that you 
> might explain it more completely.  Which would give you the opportunity 
> to get in the last, last, last word :)

You are just too generous. When can I ever get a last word in without another. 
Wouldn't the last last word be lonely?

And to the algorithm.

The principle is simple, encode the things that are known into data rather than 
code. So, suppose that we know that when we have (in this case) a successful 
search, we have to do something (anything) and based on the success of the 
'something' do something else (vague enough?). And so a conventional approach 
might be:

int ReturnValue = Search(TextString);  // as in this case

Then either:
  if ( ReturnValue == SomeValue) {
    DoSomething;
    SuccessFlag = ResultOfDoSomething;
  } else if ( ReturnValue == SomeOtherValue ) {
    DoSomethingElse;
    SuccessFlag = ResultOfDoSomethingElse;
  } else {
    SuccessFlag = SomeFailureCondition;
  }

  if ( SuccessFlag ) ASuccessStatement;

or

  switch ( ReturnValue ) {
  case SomeValue: {
    DoSomething;
    SuccessFlag = ResultOfDoSomething;
    break;
    }
  case ( SomeOtherValue ) {
    DoSomethingElse;
    SuccessFlag = ResultOfDoSomethingElse;
    break;
    }
   else SuccessFlag = SomeFailureCondition;
  }

Using the principle that 1) we know what we are going to do whenever we get a 
value, and 2) we wish to reduce code without compromising performance, we can 
reorganize the problem as:

typedef int (*Function)(void);

int Search(char * TextString);

int DoSomething      (void);   // function prototype
int DoSometingElse   (void);   // function prototype
int FailToDoSomething(void);   // failure function

int ReturnValue;

Function  FunArray[] = { DoSomething
                       , DoSomethingElse
                       , FailToDoSomething
                       };

  if ( (ReturnValue = *FunArray[Search(TextString)]) ) { statement; }

Since we Own The Universe we can guarantee that Search returns a value 
consistent with the FunArray array bounds ([0 .. n]) guaranteeing success. 

A couple of minor points:
1. This is a really simple example. If you'd like, I have actual code
   of more complex situations.
2. There is no restriction on arguments. For this example 
   I've kept it simple but I believe that the following 
   return-and-use argument sequence will work:

   typedef int (*Function)(Sometype arg);
   int Search(char * TextString, SomeType * ReturnArg);
   int DoSomething(SomeType * ReturnArg);  // and etc.

   if ( (ReturnValue = *FunArray[Search(TextString, ReturnArg)](ReturnArg)) ) {
     statement;
   }

   // Who in their right mind would do this? Me?
3. The argument is not optimized. The argument makes 
   a point by example so please poke at the argument
   and not the example.

Will this work? Yes, and often reduce performance time, generated code size, 
and maintenance costs. It is a reworking of an open problem from a code-centric 
solution to a data-centric solution by focussing and datafying things that we 
know. I like to say: "why ask a question if you know the answer".

I hope this helps, if not, then really hard actual code will follow.

art



Reply via email to