Каков стандартный подход для реализации одноразового логического переключателя? - PullRequest
1 голос
/ 21 сентября 2009

Допустим, у меня есть некоторый код, подобный следующему, и что processData выполняется сотни или даже тысячи раз в минуту:

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;
        }
    }

    // ...
}

Как следует из ее названия, atLeastOneDataPoint - это переменная, которую действительно нужно установить только один раз, однако в приведенном выше коде она устанавливается каждый раз, когда processData вызывается после первой точки данных. Естественно, я мог бы изменить строку назначения на это:

if (!atLeastOneDataPoint) atLeastOneDataPoint = true;

Но это просто заменит кучу ненужных назначений кучей ненужных булевых проверок.

Меня не беспокоит производительность этого кода; на самом деле меня просто беспокоит идея сделать что-то совершенно ненужное. Существует ли стандартный способ настройки одноразовых переключателей, такой как этот, который более интуитивно «правильный» в дизайне?

Что касается того, делает ли меня даже забота об этом плохим программистом: давайте оставим это обсуждение на другой день, пожалуйста.

Ответы [ 4 ]

4 голосов
/ 21 сентября 2009

Я бы сказал, что то, что вы уже получили, является лучшим способом: просто устанавливайте логический флаг на каждой итерации.

Если вы не беспокоитесь о производительности, я думаю, что это наиболее читаемое решение: хорошо и понятно, что происходит - я обработал правильную точку данных, поэтому установил флаг в значение true.

Даже если производительность вызывает беспокойство, я думаю, вам будет сложно найти какую-либо операцию, более эффективную, чем установка единственного логического значения в значение true.

1 голос
/ 21 сентября 2009

Callbacks

сначала зарегистрируйте функцию с именем "call_once_at_init ()", и эта функция зарегистрирует "call_always_after_init ()" для последующего использования.

0 голосов
/ 23 сентября 2009

Разве это не то, что вы хотите?

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

Это на самом деле делает atLeastOnedataPoint = true только один раз.

Даже если бы он делал это каждый раз, выполнение if (!atLeastOneDataPoint) atLeastOnedataPoint = true; должно занимать менее 100 нс (вероятно, намного меньше). Даже при 100 нс, если вы делаете это 1000 раз за одну минуту, он потребляет 100 мс = 0,1 мс из этой минуты.

Могу поспорить, у вас есть "большая рыба для жарки".

0 голосов
/ 21 сентября 2009

если вы не используете atLeastOneDataPoint в качестве первого флага в данных процесса

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

, но 10000 в минуту - ничто - беспокойство, когда его 1,5 миллиона в секунду

...