views:

138

answers:

4

Let's say I have some code like the following, and that processData gets executed hundreds or even thousands of times per minute:

class DataProcessor {
private:
    DataValidator* validator;
    bool atLeastOneDataPoint;
    bool dataIsValid(Data* dataToValidate) {
        return validator->validate(dataToValidate);
    }

public:
    // ...

    void processData(Data* dataToProcess) {
        if (dataIsValid(dataToProcess) || !atLeastOneDataPoint) {
            // process data
            // ...
            atLeastOneDataPoint = true;
        }
    }

    // ...
}

As can be inferred from its name, atLeastOneDataPoint is a variable that really only needs to get set once, yet in the code above it is set every single time processData is called after the first data point. Naturally, I could change the assignment line to this:

if (!atLeastOneDataPoint) atLeastOneDataPoint = true;

But that would simply replace a bunch of unnecessary assignments with a bunch of unnecessary Boolean checks.

I'm not concerned about the performance of this code; really I'm just bothered by the idea of doing something so totally unnecessary. Is there a standard way of setting one-time switches such as this, that is more intuitively "proper" in design?

As for whether or not even caring about this makes me a bad programmer: let's leave that discussion for another day, please.

+1  A: 

Callbacks

first register a function called "call_once_at_init()", and this function will register "call_always_after_init()" for use afterwards.

Tiemen
@Tiemen: I thought about this, and I guess my only concern would be that using callback functions could actually be LESS efficient than the over-and-over assignment.... Do you happen to know? (Granted, this is definitely more "intuitively proper," which is what I asked for; I'm just curious. I guess I want to have it both ways, and maybe that just isn't possible.)
Dan Tao
If you're only going to execute it "hundreds or thousands of times per minute", *nothing* you can do will make it matter performance-wise. Start worrying about performance when the code is executed tens of millions of times *per second*.
jalf
Supposing performance mattered, though, I think Dan's instinct is right, that the function pointer could be less efficient. Loading an address and calling it might well be slower than calling a constant address. Or might be the same speed (since a constant might be loaded from a constant pool anyway, in which case it depends what's currently in cache). Or might be irrelevant since the calling code allows the compiler to only load the function address once and keep it in a register callee-preserves register that the called code never actually uses. Or might be faster.
Steve Jessop
@jalf: Yeah, I know. Like I said, I was really just wondering if there was some obvious alternative I was missing. I think the fact is that this answer might be conceptually the best, whereas teedyay's answer (the method I was already using) makes the most practical sense, and I just need to accept that.
Dan Tao
@onebyone: Thanks for the insight. That's what I suspected as well; and as jalf and teedyay have already pointed out, it's probably not going to matter one way or the other, really.
Dan Tao
+4  A: 

I'd say what you've already got is the best way: just set the boolean flag on every iteration.

If you're not concerned about performance, I think this is the most readable solution: it's nice and obvious what's going on - I've processed a valid data point, so I set the flag to true.

Even if performance is a concern, I think you'd struggle to find any operation that's more efficient than setting a single boolean to true.

teedyay
A: 

provide you dont use atLeastOneDataPoint as a first flag in process data

void processData(Data* dataToProcess) {
   if ( (atLeastOneDataPoint = (dataIsValid(dataToProcess) || !atLeastOneDataPoint) ) ) {
      // process data
      //...
   }
}

but 10000 per minute is nothing - worry when its 1.5 million per second

pgast
A: 

Isn't this what you want?

void processData(Data* dataToProcess) {
    if (!atLeastOneDataPoint) atLeastOnedataPoint = true;
    if (dataIsValid(dataToProcess)) {
        // process data
        // ...
    }
}

This is only actually doing atLeastOnedataPoint = true once.

Even if it were doing it every time, doing if (!atLeastOneDataPoint) atLeastOnedataPoint = true; should take less than 100 ns (probably a lot less). Even at 100 ns, if you do it 1000 times in one minute, it is consuming 100us = 0.1ms out of that minute.

I bet you have "bigger fish to fry".

Mike Dunlavey
Wouldn't the branch be worse than the repeated assignment, though? (Not that you can tell without measuring, etc., etc.)
Michael Myers
@Mike: You could be right about comparison being faster than assignment. (Is it? I really am embarrassed to say I don't rightly know.) However, you've changed the logic of the code; the data needs to be processed as long as dataIsValid returns true OR there hasn't been a data point yet. By setting it before checking dataIsValid, you're essentially stripping atLeastOneDataPoint of its purpose.
Dan Tao
@Dan: That's why I posted it as a question. Possibly the test and assignment statement should be inside the following if statement, though it doesn't matter much.
Mike Dunlavey
@mmyers: You're absolutely right, though, on the off-chance that the assignment is really something more complicated, you might want to check. Forgive me, I think it's notable how much discussion arises from these penny-wise questions (including from me).
Mike Dunlavey