Кэширование дорогих данных в C++ - ограниченные по объему функцией помехи по сравнению с изменяемыми членскими переменными

  1. Вам нужно будет создать кастом input.
  2. Вам нужно будет перехватить и обновить функцию input.onChange редукса.
  3. Необязательно - Если вы хотите, чтобы другие значения формы влияли на это значение, то используйте formSelector reduxForm с connect [116] для доступа к formProps внутри компонента в this.props (приведенный ниже рабочий пример уже включает эту функциональность)
  4. components / CustomInput.js

    import React from "react";
    
    const CustomInput = ({
      // we'll intercept redux's "onChange" func, while leaving the other 
      // input props as is in "inputProps"
      input: { onChange, ...inputProps }, 
      // the "handleChange" func below is the parent func that will handle input changes
      handleChange, 
      // "rest" contains any additional properties (className, placeholder, type ...etc)
      ...rest 
    }) => (
      // we spread out the "inputProps" and the "rest" of the props, then we add
      // an "onChange" event handler that returns the "event" and the 
      // input's "onChange" func to our "handleChange" parent func
       handleChange(e, onChange)} />
    );
    
    export default CustomInput;
    

    контейнеров / Form.js

    class ControlledFormValue extends PureComponent { 
    
      // this parent func will handle updates through the "event.target.value"; 
      // the value can be changed/altered and then passed to the input's
      // "onChange" func to update the field
      handleChange = ({ target: { value } }, onChange) => {
        // this will alter the value by adding a "-" after each input update
        onChange(`${value}-`);
        setTimeout(() => console.log(this.props.values), 500);
      };
    
      render() {
        return (
          
    ...etc
    ); } }

    Рабочий пример : https://codesandbox.io/s/lx1r4yjwy7

9
задан Dominic Rodger 5 March 2009 в 14:15
поделиться

4 ответа

Я перенес бы реализацию LongRunningOperationToFetchFactor с чем-то вроде этого. Я использую ограниченные по объему блокировки Повышения, но Вы можете так что-то похожее с другими платформами блокировки.

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <map>

using namespace std;

static boost::mutex myMutex;
static map<int,double> results;

double CachedLongRunningOperationToFetchFactor( int key )
{

   {
       boost::mutex::scoped_lock lock(myMutex);

       map<int,double>::iterator iter = results.find(key);
       if ( iter != results.end() )
       {
          return (*iter).second;
       }
   }
   // not in the Cache calculate it
   result = LongRunningOperationToFetchFactor( key );
   {
       // we need to lock the map again
       boost::mutex::scoped_lock lock(myMutex);
       // it could be that another thread already calculated the result but
       // map assignment does not care.
       results[key] = result;
   }
   return result;
}

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

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

5
ответ дан 4 December 2019 в 21:12
поделиться

Если я не понимаю, для меня кажется очевидным, что Вы хотите сделать это помехами:

double AdjustData(double d) const {
   static const double kAdjustFactor = LongRunningOperationToFetchFactor();
   return kAdjustFactor * d;
}

Тем путем Вы только выбираете фактор однажды.

0
ответ дан 4 December 2019 в 21:12
поделиться

Я не сделал бы этот кэш локальными помехами. Изменяемая карта является решением для кэширования результатов. Иначе это сделает Вашу функцию бесполезной, поскольку различные объекты Вашего класса совместно используют тот же кэш, как локальный статический кэш является тем же для всех объектов. Можно использовать локальные помехи, если результат не зависит от объекта все же. Но затем я спросил бы меня, почему функция является нестатическим членом Вашего объекта, если это не должно получать доступ ни к какому состоянию его.

Поскольку Вы говорите, что это должно быть ориентировано на многопотоковое исполнение - если различные потоки могут назвать функцию членства на том же объекте, Вы, вероятно, хотите использовать взаимное исключение. boost::thread хорошая библиотека должна использовать.

4
ответ дан 4 December 2019 в 21:12
поделиться

Можно использовать шаблон "одиночка" (1) для с классом, который выполняет продолжительную операцию и кэширует результат. Этот экземпляр мог затем использоваться в функциях членства константы других классов. Полагайте, что взаимное исключение для защиты вставляет и извлечения от структуры данных карты для потокобезопасности. Если многопоточная производительность является огромной проблемой, то можно отметить ключи как происходящие, чтобы препятствовать тому, чтобы несколько потоков вычислили тот же ключ одновременно.

#include <cstdlib>
#include <iostream>
#include <map>

using namespace std;

class FactorMaker {
    map<int, double> cache;

    double longRunningFetch(int key)
    {
        const double factor = static_cast<double> (rand()) / RAND_MAX;
        cout << "calculating factor for key " << key << endl;
        // lock
        cache.insert(make_pair(key, factor));
        // unlock
        return factor;
    }

public:
    double getFactor(int key) {
        // lock
        map<int, double>::iterator it = cache.find(key);
        // unlock
        return (cache.end() == it) ? longRunningFetch(key) : it->second;
    }
};

FactorMaker & getFactorMaker()
{
    static FactorMaker instance;
    return instance;
}

class UsesFactors {
public:
    UsesFactors() {}

    void printFactor(int key) const
    {
        cout << getFactorMaker().getFactor(key) << endl;
    }
};

int main(int argc, char *argv[])
{
    const UsesFactors obj;

    for (int i = 0; i < 10; ++i)
        obj.printFactor(i);

    for (int i = 0; i < 10; ++i)
        obj.printFactor(i);

    return EXIT_SUCCESS;
}

(1) Шаблон "одиночка" может быть чрезвычайно пропущен. Так, воздержитесь от схождения с ума с ним, если Вы видите его впервые.

1
ответ дан 4 December 2019 в 21:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: