Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief benchmark for comparing the cryptographic providers used in the crypto plugin.
5 : *
6 : * @copyright BSD License (see doc/LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 : #include <backendbuilder.hpp>
11 : #include <kdbconfig.h>
12 : #include <kdbtimer.hpp>
13 :
14 : #include <unistd.h>
15 :
16 : #include <fstream>
17 : #include <iostream>
18 :
19 : extern "C" char ** environ;
20 :
21 : // test key is located at src/plugins/crypto/test_key.asc
22 : #define GPG_TEST_KEY_ID "DDEBEF9EE2DC931701338212DAF635B17F230E8D"
23 :
24 : enum PluginVariant
25 : {
26 : NO_CRYPTO = 0, ///< use no crypto variant
27 : CRYPTO_OPENSSL = 1,
28 : CRYPTO_GCRYPT = 2,
29 : CRYPTO_BOTAN = 3,
30 : FCRYPT = 4
31 : };
32 :
33 0 : static const std::string plugin_variant_names[] = { "no_crypto_plugin", "crypto_openssl", "crypto_gcrypt", "crypto_botan", "fcrypt" };
34 :
35 : long long nr_keys = 100LL; // should be higher but crypto performance is actually quite bad atm
36 :
37 : const int benchmarkIterations = 11; // is a good number to not need mean values for median
38 :
39 0 : kdb::KeySet toWrite;
40 :
41 : template <enum PluginVariant VARIANT>
42 0 : kdb::Key getMountpointForIteration (int iteration)
43 : {
44 0 : return kdb::Key ("user/benchmark_" + plugin_variant_names[VARIANT] + std::to_string (iteration), KEY_END);
45 : }
46 :
47 : template <enum PluginVariant VARIANT>
48 0 : kdb::Key mountBackend (int iteration)
49 : {
50 : using namespace kdb;
51 : using namespace kdb::tools;
52 :
53 0 : Key mp = getMountpointForIteration<VARIANT> (iteration);
54 0 : std::string cf = "benchmark_" + plugin_variant_names[VARIANT] + "_" + std::to_string (iteration) + ".ecf";
55 0 : unlink (cf.c_str ());
56 :
57 0 : KDB kdb;
58 0 : KeySet mountConfig;
59 0 : kdb.get (mountConfig, "system/elektra/mountpoints");
60 :
61 0 : MountBackendBuilder b;
62 0 : b.setMountpoint (mp, KeySet (0, KS_END));
63 0 : b.addPlugin (PluginSpec ("resolver"));
64 0 : b.useConfigFile (cf);
65 :
66 0 : b.addPlugin (PluginSpec ("dump"));
67 : if (VARIANT != NO_CRYPTO)
68 : {
69 0 : KeySet pluginConfig;
70 0 : pluginConfig.append (Key ("user/encrypt/key", KEY_VALUE, GPG_TEST_KEY_ID, KEY_END));
71 0 : pluginConfig.append (Key ("user/gpg/unit_test", KEY_VALUE, "1", KEY_END));
72 0 : b.addPlugin (PluginSpec (plugin_variant_names[VARIANT], pluginConfig));
73 : }
74 :
75 0 : b.validated ();
76 0 : b.serialize (mountConfig);
77 0 : kdb.set (mountConfig, "system/elektra/mountpoints");
78 0 : kdb.close ();
79 0 : return mp;
80 : }
81 :
82 : template <enum PluginVariant VARIANT>
83 0 : __attribute__ ((noinline)) void benchmark_crypto_set (int iteration)
84 : {
85 : using namespace kdb;
86 : using namespace kdb::tools;
87 0 : static Timer t (plugin_variant_names[VARIANT]);
88 :
89 0 : Key mp = mountBackend<VARIANT> (iteration);
90 :
91 : {
92 0 : KDB kdb;
93 0 : KeySet ks;
94 :
95 0 : kdb.get (ks, mp);
96 0 : for (int i = 0; i < nr_keys; ++i)
97 : {
98 : // clang-format off
99 0 : ks.append (Key (mp.getName () + "/k" + std::to_string (i),
100 : KEY_VALUE, "value",
101 : KEY_META, "crypto/encrypt", "1",
102 : KEY_END));
103 : // clang-format on
104 : }
105 :
106 : /***************************************************************************
107 : * start of measurement
108 : **************************************************************************/
109 0 : t.start ();
110 0 : kdb.set (ks, mp);
111 0 : t.stop ();
112 : /***************************************************************************
113 : * end of measurement
114 : **************************************************************************/
115 :
116 0 : kdb.close ();
117 : }
118 :
119 0 : std::cout << t;
120 0 : }
121 :
122 : template <enum PluginVariant VARIANT>
123 0 : __attribute__ ((noinline)) void benchmark_crypto_get (int iteration)
124 : {
125 : using namespace kdb;
126 : using namespace kdb::tools;
127 0 : static Timer t (plugin_variant_names[VARIANT]);
128 :
129 0 : KDB kdb;
130 0 : KeySet ks;
131 0 : Key mp = getMountpointForIteration<VARIANT> (iteration);
132 :
133 : /***************************************************************************
134 : * start of measurement
135 : **************************************************************************/
136 0 : t.start ();
137 0 : kdb.get (ks, mp);
138 0 : t.stop ();
139 : /***************************************************************************
140 : * end of measurement
141 : **************************************************************************/
142 :
143 0 : kdb.close ();
144 0 : std::cout << t;
145 0 : }
146 :
147 :
148 0 : void computer_info ()
149 : {
150 0 : std::cout << std::endl;
151 0 : std::cout << std::endl;
152 : #ifndef _WIN32
153 : char hostname[1024];
154 0 : gethostname (hostname, 1023);
155 0 : std::cout << "hostname " << hostname << std::endl;
156 : #endif
157 : #ifdef __GNUC__
158 0 : std::cout << "gcc: " << __GNUC__ << std::endl;
159 : #endif
160 : #ifdef __INTEL_COMPILER
161 : std::cout << "icc: " << __INTEL_COMPILER << std::endl;
162 : #endif
163 : #ifdef __clang__
164 : std::cout << "clang: " << __clang__ << std::endl;
165 : #endif
166 0 : std::cout << "sizeof(int) " << sizeof (int) << std::endl;
167 0 : std::cout << "sizeof(long) " << sizeof (long) << std::endl;
168 0 : std::cout << "sizeof(long long) " << sizeof (long long) << std::endl;
169 0 : std::cout << "number of keys " << nr_keys << std::endl;
170 0 : std::cout << std::endl;
171 0 : }
172 :
173 0 : int main (int argc, char ** argv)
174 : {
175 0 : if (argc > 1)
176 : {
177 0 : nr_keys = atoll (argv[1]);
178 : }
179 :
180 0 : computer_info ();
181 :
182 : #ifdef HAVE_CLEARENV
183 0 : clearenv ();
184 : #endif
185 :
186 0 : std::cout << "----- KDB SET -----" << std::endl;
187 0 : for (int i = 0; i < benchmarkIterations; ++i)
188 : {
189 0 : std::cout << i << std::endl;
190 :
191 0 : benchmark_crypto_set<NO_CRYPTO> (i);
192 0 : benchmark_crypto_set<CRYPTO_OPENSSL> (i);
193 0 : benchmark_crypto_set<CRYPTO_GCRYPT> (i);
194 0 : benchmark_crypto_set<CRYPTO_BOTAN> (i);
195 0 : benchmark_crypto_set<FCRYPT> (i);
196 : }
197 :
198 0 : std::cout << "----- KDB GET -----" << std::endl;
199 0 : for (int i = 0; i < benchmarkIterations; ++i)
200 : {
201 0 : std::cout << i << std::endl;
202 :
203 0 : benchmark_crypto_get<NO_CRYPTO> (i);
204 0 : benchmark_crypto_get<CRYPTO_OPENSSL> (i);
205 0 : benchmark_crypto_get<CRYPTO_GCRYPT> (i);
206 0 : benchmark_crypto_get<CRYPTO_BOTAN> (i);
207 0 : benchmark_crypto_get<FCRYPT> (i);
208 : }
209 0 : }
|