x014.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "xmath.h"
4 #include "xtools.h"
5 #include <chrono>
6 #include <cmath>
7 #include <functional>
8 #include <iostream>
9 #include <map>
10 
11 namespace nmx::apps::x014 {
12 
17 template<class X, class Y, bool DEBUG = false>
18 class Cache
19 {
20 private:
21  //Speicher für (x,f(x))
22  std::map<X, Y> _table;
23  //Zeiger auf Funktionsobjekt f(x)
24  std::function<Y(X)> _fn;
25 
26 public:
31  Cache(Y (*fn)(X))
32  : _fn{ fn } {}
33 
39  Y get(X x) {
40  const auto fitr = _table.find(x);
41  if (fitr != _table.end()) {
42  // Wert wurde im Speicher gefunden
43  if constexpr (DEBUG) {
44  std::cout << "from cache:";
45  }
46  return fitr->second;
47  }
48  Y val = _fn(x); //Wert wird berechnet
49  _table[x] = val; //...und gespeichert
50  return val;
51  }
52 
57  auto size() const { return _table.size(); }
58 }; //Cache
59 
65 double fac(size_t n) {
66  if (n < 1000) {
67  return n == 0 ? 1 : n * fac(n - 1);
68  }
69  //Stirling-Formel
70  return std::sqrt(2 * Math::PI * n) * std::pow(n / Math::E, n);
71 }
72 
76 inline void ex1() {
77  Cache<size_t, double> c1{ fac }; //ohne Meldung
78  for (auto n : { 2, 9, 50, 100, 2, 9 }) {
79  std::cout << n << "! =" << c1.get(static_cast<size_t>(n)) << std::endl;
80  }
81  std::cout << "---------------------------" << std::endl;
82  Cache<size_t, double, true> c2{ fac }; //mit Meldung
83  for (auto n : { 2, 9, 50, 100, 2, 9 }) {
84  std::cout << n << "! =" << c2.get(static_cast<size_t>(n)) << std::endl;
85  }
86 }
87 
91 inline void ex2() {
92  //vermeide lange Bezeichner
93  using namespace std::chrono;
94 
96  //Anzahl der Summenterme
97  const size_t N = 1e5;
98  //Berechnung der Summe mit Zeitmessung
99  double sum1 = 0;
100  auto start1 = steady_clock::now();
101  for (size_t n = 0; n < N; n++) {
102  sum1 += 1 / c1.get(n);
103  }
104  auto end1 = steady_clock::now();
105  auto dt1 = duration<double, std::milli>(end1 - start1).count();
106 
107  //Wiederholung der Berechnung
108  double sum2 = 0;
109  auto start2 = steady_clock::now();
110  for (size_t n = 0; n < N; n++) {
111  sum2 += 1 / c1.get(n);
112  }
113  auto end2 = steady_clock::now();
114  auto dt2 = duration<double, std::milli>(end2 - start2).count();
115 
116  //Ausgabe der Ergebnisse auf dem Bildschirm
117  std::cout << "dt1=" << dt1 << " ms" << std::endl;
118  std::cout << "value=" << sum1 << std::endl;
119  std::cout << "---------------------------" << std::endl;
120  std::cout << "dt2=" << dt2 << " ms" << std::endl;
121  std::cout << "value=" << sum2 << std::endl;
122  std::cout << "---------------------------" << std::endl;
123  std::cout << "dt2/dt1=" << dt2 / dt1 << std::endl;
124  std::cout << "cache size=" << c1.size() << std::endl;
125 }
126 
127 } // namespace nmx::apps::x014
auto size() const
size
Definition: x014.h:57
void ex2()
ex2 Berechnung eines Näherungswerts für e mit 1+1/2!+1/3!+...
Definition: x014.h:91
static constexpr double E
Definition: xmath.h:13
The Cache class Erzeugen von Zwischenspeicher für Funktionswerte.
Definition: x014.h:18
void ex1()
cppx6 Beispiel
Definition: x014.h:76
Cache(Y(*fn)(X))
Cache Konstruktor.
Definition: x014.h:31
double fac(size_t n)
fac Berechnung von n! exakt oder mit einer Näherungsformel
Definition: x014.h:65
static constexpr double PI
Definition: xmath.h:11