Fabcoin Core  0.16.2
P2P Digital Currency
main.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #include <clocale>
23 #include <fstream>
24 #include <iostream>
25 #include <boost/algorithm/string.hpp>
26 #include <boost/filesystem.hpp>
28 #include <libdevcore/CommonIO.h>
29 #include <libdevcore/RLP.h>
30 #include <libdevcore/SHA3.h>
31 #include <libdevcore/MemoryDB.h>
32 #include <libdevcore/TrieDB.h>
33 #include <libdevcrypto/Common.h>
34 #include <libdevcrypto/CryptoPP.h>
35 using namespace std;
36 using namespace dev;
37 namespace js = json_spirit;
38 
39 void help()
40 {
41  cout
42  << "Usage bench <mode> [OPTIONS]" << endl
43  << "Modes:" << endl
44  << " trie Trie benchmarks." << endl
45  << endl
46  << "General options:" << endl
47  << " -h,--help Print this help message and exit." << endl
48  << " -V,--version Show the version and exit." << endl
49  ;
50  exit(0);
51 }
52 
53 void version()
54 {
55  cout << "bench part of dev suite version " << dev::Version << endl;
56  exit(0);
57 }
58 
59 /*
60 The equivalent of setlocale(LC_ALL, ā€œCā€) is called before any user code is run.
61 If the user has an invalid environment setting then it is possible for the call
62 to set locale to fail, so there are only two possible actions, the first is to
63 throw a runtime exception and cause the program to quit (default behaviour),
64 or the second is to modify the environment to something sensible (least
65 surprising behaviour).
66 
67 The follow code produces the least surprising behaviour. It will use the user
68 specified default locale if it is valid, and if not then it will modify the
69 environment the process is running in to use a sensible default. This also means
70 that users do not need to install language packs for their OS.
71 */
73 {
74 #if __unix__
75  if (!std::setlocale(LC_ALL, ""))
76  {
77  setenv("LC_ALL", "C", 1);
78  }
79 #endif
80 }
81 
82 enum class Mode {
83  Trie,
84  SHA3
85 };
86 
87 enum class Alphabet
88 {
89  Low, Mid, All
90 };
91 
93 {
94 public:
95  StandardMap() = default;
96  StandardMap(Alphabet _alphabet, unsigned _count, unsigned _minKey, unsigned _diffKey): m_alphabet(_alphabet), m_count(_count), m_minKey(_minKey), m_diffKey(_diffKey) {}
97 
98  vector<pair<bytes, bytes>> make() const
99  {
100  string const c_low = "abcdef";
101  string const c_mid = "@QWERTYUIOPASDFGHJKLZXCVBNM[/]^_";
102 
103  h256 seed;
104  vector<pair<bytes, bytes>> input;
105  for (unsigned j = 0; j < m_count; ++j)
106  {
107  bytes k = m_alphabet == Alphabet::All ? randomBytes(m_minKey, m_diffKey, &seed) : randomWord(m_alphabet == Alphabet::Low ? c_low : c_mid, m_minKey, m_diffKey, &seed);
108  bytes v = randomValue(&seed);
109  input.push_back(make_pair(k, v));
110  }
111  return input;
112  }
113 
114 private:
116  unsigned m_count;
117  unsigned m_minKey;
118  unsigned m_diffKey;
119 
120  static bytes randomWord(bytesConstRef _alphabet, unsigned _min, unsigned _diff, h256* _seed)
121  {
122  assert(_min + _diff < 33);
123  *_seed = sha3(*_seed);
124  unsigned l = _min + (*_seed)[31] % (_diff + 1);
125  bytes ret;
126  for (unsigned i = 0; i < l; ++i)
127  ret.push_back(_alphabet[(*_seed)[i] % _alphabet.size()]);
128  return ret;
129  }
130 
131  static bytes randomBytes(unsigned _min, unsigned _diff, h256* _seed)
132  {
133  assert(_min + _diff < 33);
134  *_seed = sha3(*_seed);
135  unsigned l = _min + (*_seed)[31] % (_diff + 1);
136  return _seed->ref().cropped(0, l).toBytes();
137  }
138 
139  static bytes randomValue(h256* _seed)
140  {
141  *_seed = sha3(*_seed);
142  if ((*_seed)[0] % 2)
143  return bytes(1, (*_seed)[31]);
144  else
145  return _seed->asBytes();
146  }
147 };
148 
149 int main(int argc, char** argv)
150 {
152  Mode mode = Mode::Trie;
153 
154  for (int i = 1; i < argc; ++i)
155  {
156  string arg = argv[i];
157  if (arg == "-h" || arg == "--help")
158  help();
159  else if (arg == "trie")
160  mode = Mode::Trie;
161  else if (arg == "sha3")
162  mode = Mode::SHA3;
163  else if (arg == "-V" || arg == "--version")
164  version();
165  }
166 
167  if (mode == Mode::Trie)
168  {
169  unordered_map<string, StandardMap> maps =
170  {
171  { "six-low", StandardMap(Alphabet::Low, 1000, 6, 0) },
172  { "six-mid", StandardMap(Alphabet::Mid, 1000, 6, 0) },
173  { "six-all", StandardMap(Alphabet::All, 1000, 6, 0) },
174  { "mix-mid", StandardMap(Alphabet::Mid, 1000, 1, 5) },
175  };
176  unsigned trials = 50;
177  for (auto const& sm: maps)
178  {
179  MemoryDB mdb;
180  GenericTrieDB<MemoryDB> t(&mdb);
181  t.init();
182 
183  auto map = sm.second.make();
184  Timer timer;
185  for (unsigned i = 0; i < trials; ++i)
186  for (auto const& i: map)
187  t.insert(&i.first, &i.second);
188  auto e = timer.elapsed() / trials;
189 
190  cout << sm.first << ": " << e * 1000000 << " us, root=" << t.root() << endl;
191  }
192  }
193  else if (mode == Mode::SHA3)
194  {
195  unsigned trials = 50;
196  Timer t;
197  for (unsigned trial = 0; trial < trials; ++trial)
198  {
199  h256 s;
200  for (unsigned i = 0; i < 1000; ++i)
201  s = sha3(s);
202  }
203  cout << "sha3 x 1000: " << t.elapsed() / trials * 1000000 << "us " << endl;
204  }
205 
206  return 0;
207 }
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
void help()
Definition: main.cpp:39
unsigned m_minKey
Definition: main.cpp:117
SHA3 message digest base class.
Definition: sha3.h:28
unsigned m_diffKey
Definition: main.cpp:118
Merkle Patricia Tree "Trie": a modifed base-16 Radix tree.
Definition: TrieDB.h:64
static bytes randomBytes(unsigned _min, unsigned _diff, h256 *_seed)
Definition: main.cpp:131
StandardMap(Alphabet _alphabet, unsigned _count, unsigned _minKey, unsigned _diffKey)
Definition: main.cpp:96
evm_mode mode
Definition: SmartVM.cpp:47
std::string randomWord()
Creates a random, printable, word.
Definition: CommonData.cpp:88
std::hash for asio::adress
Definition: Common.h:323
assert(len-trim+(2 *lenIndices)<=WIDTH)
static bytes randomWord(bytesConstRef _alphabet, unsigned _min, unsigned _diff, h256 *_seed)
Definition: main.cpp:120
vector_ref< _T > cropped(size_t _begin, size_t _count) const
Definition: vector_ref.h:62
void version()
Definition: main.cpp:53
static bytes randomValue(h256 *_seed)
Definition: main.cpp:139
double elapsed() const
Definition: Common.h:280
void setDefaultOrCLocale()
Definition: main.cpp:72
bytesRef ref()
Definition: FixedHash.h:133
int main(int argc, char **argv)
Definition: main.cpp:149
h256 const & root() const
Definition: TrieDB.h:99
rpc::SessionManager sm
Definition: shhrpc.cpp:60
std::vector< byte > bytes
Definition: Common.h:75
size_t size() const
Definition: vector_ref.h:55
bytes asBytes() const
Definition: FixedHash.h:145
vector< pair< bytes, bytes > > make() const
Definition: main.cpp:98
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
Definition: SHA3.cpp:214
char const * Version
Definition: Common.cpp:36
unsigned m_count
Definition: main.cpp:116
#define e(i)
Definition: sha.cpp:733
Alphabet m_alphabet
Definition: main.cpp:115
Mode
Definition: main.cpp:82
Alphabet
Definition: main.cpp:87
void insert(bytes const &_key, bytes const &_value)
Definition: TrieDB.h:103