19 April 2022

C++ 核心指南目录

F.8: Prefer pure functions

理由

纯函数更容易推导,更容易优化(甚至并行处理),更容易做成记忆函数( memoize )。

所谓的纯函数(pure function)即在任何时候,只要输入一样的参数,它就会返回一样的结果。不会产生任何副作用,副作用包括修改输入的参数原来的变量、调用 IO 输入输出流,即改变 IO 输出值。

例子

template<class T>
auto square(T t) { return t * t; }

int main()
{
    cout << square(10) << endl;
    cout << square(10.1) << endl;
    return 0;
}
100
102.01

再看看以下例子,我们把一个纯函数做成 memoize 之后,可以极大的提升计算速度:

// -*- compile-command: "g++ -std=c++20 code.cpp && ./a"; -*-
#include <iostream>
#include <chrono>
#include <map>
#include <gsl/gsl>
using namespace std;
using namespace gsl;
using namespace std::chrono;
std::function<unsigned(unsigned)> fib = [](unsigned n)
{
    if(n<=1)
        return n;
    return fib(n-1)+fib(n-2);
};
template<typename InType, typename OutType>
std::function<OutType(InType)> memoize(std::function<OutType(InType)> foo)
{
    return [foo](InType n){
        static map<InType, OutType> memo;

        OutType ret;
        if(memo.count(n)>0) {
            ret =memo[n];
            return ret;
        }
        ret=foo(n);
        memo[n]=ret;
        return ret;
    };
}

auto fib1 = memoize(fib);

void calc_time(unsigned n) {
    steady_clock::time_point begin = steady_clock::now();
    fib1(n);
    steady_clock::time_point end = steady_clock::now();
    std::cout << "Time difference = "
              << duration_cast<nanoseconds> (end - begin).count()
              << "[ns]"
              << std::endl;
}

int main()
{
    calc_time(20);
    calc_time(20);
}
Time difference = 562700[ns]
Time difference = 200[ns]