Запрет на повторный перерасчет функции - страница 2

 
Aleksey Vyazmikin:

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

Можно например сделать класс в котором хранятся предыдущие параметры. И перед расчетом проверять изменились ли они.

class Trader
{
private:
 int Param1;
....
int function(int param1, ....)
}

int Trader::function(int param1 ...)
{
  if (param1!=Param1)
  {
    //расчеты
    Param1 = param1
  }
}
 
Georgiy Merts:

У тебя должны сохраняться входные переменные функции и результат. (Лично я бы сделал их членами класса, в котором эта самая функция выполняется, статическими или нет - в зависимости от конкретной архитектуры системы).

Далее, при входе в функцию сравниваешь входные переменные с сохраненными. Если они такие же - возвращаешь результат. Если нет - то вычисляешь значение, и сохраняешь результат и входные переменные.

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

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

 
Vitalii Ananev:

Можно например сделать класс в котором хранятся предыдущие параметры. И перед расчетом проверять изменились ли они.

Вот в ООП я полный дуб! Однако, кроме параметров надо сохранять и дату бара тогда, что б учитывать необходимость перерасчета при появлении баров в будущем?

 
Aleksey Vyazmikin:

Вот в ООП я полный дуб! Однако, кроме параметров надо сохранять и дату бара тогда, что б учитывать необходимость перерасчета при появлении баров в будущем?

Aleksey Vyazmikin:

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

Многомерный массив из разных типов переменных не надо делать. Если с ОПП не дружите, тогда храните параметры в структуре (struct). В ней можно объединить разные типы  переменных, в том числе и дату бара. Потом при вызове функции проверять данные хранящиеся в структуре и переданные параметры. Если какой то из параметров отличается выполнять расчеты и запомнить новые параметры.

struct SParam
{ 
   int   Param1;     
   ....
   double  ParamN;     
   datetime BarTime;
};
 
Aleksey Vyazmikin:

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

Ну тут получается что-то вроде кэша.

Я бы сделал так.

Берешь структуру - поля это входные данные и выходное значение. Кроме того - одно поле - это счетчик обращений.

Создаешь массив этих структур. Максимальный размер массива - надо глядеть по сложности вычисления. Если функция очень сложная - то и размер массива можно брать побольше.

Первоначально заполняешь массив невалидными входными значениями с нулевыми счетчиками обращений.

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

Если нужная комбинация входных значений находится - счетчик обращений увеличиваешь на единицу, и возвращаешь значение.

Если нужная комбинация не находится - то производишь все нужные вычисления для данной функции, заполняешь структуру, в которой был минимальный счетчик обращений, устанавливая счетчик на единицу.  Возвращаешь найденное значение.

Вот и все.

Если какая-то комбинация параметров нужна часто - то она будет иметь большой счетчик, и все время будет "готова к употреблению". Редкие комбинации параметров - будут заменяться.

Ну и можно брать не массив, а список, и организовать очередь - при этом вызываемая структура - будет переноситься в начало очереди. Это уже - по ситуации... Да и организация списка удобна через потомков CObject, а ты, как говоришь, не больно-то с ООП дружишь..

Весь кэш я, конечно, сделал бы отдельным классом (возможно, даже темплейтом, чтобы можно было менять структуру входных данных), но это не обязательно.

 
Aleksey Vyazmikin:

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

Внутри функции статические переменные, которые всегда возвращаются в конце расчетов (или как там они передеаются).
А в начале функции проверяется флаг, если флаг сброшен - переходим в конец и возвращаем то что есть.

Сам флаг контролировать в начале онтика.

 

Georgiy Merts, идея правильная. Но на фига нужно сохранять все в структуре. Я в таких случаях делаю так:

1. Захожу в функцию.

2. Перевожу все параметры в строку.

3. Перевожу строку в число например с помощью функции Adler32. которая тут есть где то в статьях.

4. Ищу допустим это число в массиве long Kesh. Если нахожу то результат работы функции лежит по соответствующему элементу double KeshOtvet.

5. Если не удалось найти число из пункта 3 в массиве . То выполняю функцию и сохраняю пару новых значений.

 
pivomoe:

Georgiy Merts, идея правильная. Но на фига нужно сохранять все в структуре. Я в таких случаях делаю так:

1. Захожу в функцию.

2. Перевожу все параметры в строку.

3. Перевожу строку в число например с помощью функции Adler32. которая тут есть где то в статьях.

4. Ищу допустим это число в массиве long Kesh. Если нахожу то результат работы функции лежит по соответствующему элементу double KeshOtvet.

5. Если не удалось найти число из пункта 3 в массиве . То выполняю функцию и сохраняю пару новых значений.

Всякая структура, по сути - строка, поэтому п.2 - лишний. 

Если в п.4 искать эту строку, без какого-либо ее преобразования, то и п.3 станет лишним. 

Экономия, однако... 

 
Алексей Тарабанов:

Всякая структура, по сути - строка, поэтому п.2 - лишний. 

Если в п.4 искать эту строку, без какого-либо ее преобразования, то и п.3 станет лишним. 

Экономия, однако... 

C точки зрения реальной торговли вы правы, если конечно параметры не занимают мегабайты.  С точки зрения оптимизации ( если использовать этот подход для оптимизации, сохранять результаты на диск ) наверное прав я т.к процедура скачивания с диска занимает много времени.

 
Aleksey Vyazmikin:

Вот в ООП я полный дуб! Однако, кроме параметров надо сохранять и дату бара тогда, что б учитывать необходимость перерасчета при появлении баров в будущем?

Алексей, Виталий показал простейший пример ООП, но самый эффективный. Все остальные примеры так или иначе сводятся к такому-же алгоритму, но со своеобразным вывертом. Как например второй вариант Виталия со структурой. Всё то-же самое, но с определёнными сложностями. Постарайся понять пару элементарных понятий ООП и всё встанет на свои места.

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