KiCad PCB EDA Suite
io_benchmark.cpp File Reference
#include <wx/wx.h>
#include <richio.h>
#include <chrono>
#include <ios>
#include <functional>
#include <iostream>
#include <fstream>
#include <wx/wfstream.h>
#include <wx/filename.h>
#include <qa_utils/stdstream_line_reader.h>
#include <qa_utils/utility_registry.h>

Go to the source code of this file.

Classes

struct  BENCH_REPORT
 
struct  BENCHMARK
 

Typedefs

using CLOCK = std::chrono::steady_clock
 
using TIME_PT = std::chrono::time_point< CLOCK >
 
using BENCH_FUNC = std::function< void(const wxFileName &, int, BENCH_REPORT &)>
 

Functions

static void bench_fstream (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using a raw std::ifstream, with no LINE_READER wrapper. More...
 
static void bench_fstream_reuse (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using a raw std::ifstream, with no LINE_READER wrapper. More...
 
template<typename LR >
static void bench_line_reader (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using a given LINE_READER implementation. More...
 
template<typename LR >
static void bench_line_reader_reuse (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using a given LINE_READER implementation. More...
 
static void bench_string_lr (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using STRING_LINE_READER on string data read into memory from a file using std::ifstream, but read the data fresh from the file each time. More...
 
static void bench_string_lr_reuse (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using STRING_LINE_READER on string data read into memory from a file using std::ifstream. More...
 
template<typename S >
static void bench_wxis (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using an INPUTSTREAM_LINE_READER with a given wxInputStream implementation. More...
 
template<typename S >
static void bench_wxis_reuse (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using an INPUTSTREAM_LINE_READER with a given wxInputStream implementation. More...
 
template<typename WXIS >
static void bench_wxbis (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using a INPUTSTREAM_LINE_READER with a given wxInputStream implementation, buffered with wxBufferedInputStream. More...
 
template<typename WXIS >
static void bench_wxbis_reuse (const wxFileName &aFile, int aReps, BENCH_REPORT &report)
 Benchmark using a INPUTSTREAM_LINE_READER with a given wxInputStream implementation, buffered with wxBufferedInputStream. More...
 
static wxString getBenchFlags ()
 Construct string of all flags used for specifying benchmarks on the command line. More...
 
static wxString getBenchDescriptions ()
 Usage description of a benchmakr spec. More...
 
BENCH_REPORT executeBenchMark (const BENCHMARK &aBenchmark, int aReps, const wxFileName &aFilename)
 
int io_benchmark_func (int argc, char *argv[])
 

Variables

static std::vector< BENCHMARKbenchmarkList
 List of available benchmarks. More...
 
static bool registered
 

Typedef Documentation

◆ BENCH_FUNC

using BENCH_FUNC = std::function<void(const wxFileName&, int, BENCH_REPORT&)>

Definition at line 60 of file io_benchmark.cpp.

◆ CLOCK

using CLOCK = std::chrono::steady_clock

Definition at line 41 of file io_benchmark.cpp.

◆ TIME_PT

using TIME_PT = std::chrono::time_point<CLOCK>

Definition at line 42 of file io_benchmark.cpp.

Function Documentation

◆ bench_fstream()

static void bench_fstream ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using a raw std::ifstream, with no LINE_READER wrapper.

The stream is recreated for each cycle.

Definition at line 75 of file io_benchmark.cpp.

76{
77 std::string line;
78
79 for( int i = 0; i < aReps; ++i)
80 {
81 std::ifstream fstr( aFile.GetFullPath().ToUTF8() );
82
83 while( getline( fstr, line ) )
84 {
85 report.linesRead++;
86 report.charAcc += (unsigned char) line[0];
87 }
88
89 fstr.close();
90 }
91}
unsigned charAcc
Char accumulator, used to prevent compilers optimising away otherwise unused line buffers,...
unsigned linesRead

References BENCH_REPORT::charAcc, and BENCH_REPORT::linesRead.

◆ bench_fstream_reuse()

static void bench_fstream_reuse ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using a raw std::ifstream, with no LINE_READER wrapper.

The stream is not recreated for each cycle, just reset.

Definition at line 98 of file io_benchmark.cpp.

99{
100 std::string line;
101 std::ifstream fstr( aFile.GetFullPath().ToUTF8() );
102
103 for( int i = 0; i < aReps; ++i)
104 {
105 while( getline( fstr, line ) )
106 {
107 report.linesRead++;
108 report.charAcc += (unsigned char) line[0];
109 }
110 fstr.clear() ;
111 fstr.seekg(0, std::ios::beg) ;
112 }
113
114 fstr.close();
115}

References BENCH_REPORT::charAcc, and BENCH_REPORT::linesRead.

◆ bench_line_reader()

template<typename LR >
static void bench_line_reader ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using a given LINE_READER implementation.

The LINE_READER is recreated for each cycle.

Definition at line 123 of file io_benchmark.cpp.

124{
125 for( int i = 0; i < aReps; ++i)
126 {
127 LR fstr( aFile.GetFullPath() );
128 while( fstr.ReadLine() )
129 {
130 report.linesRead++;
131 report.charAcc += (unsigned char) fstr.Line()[0];
132 }
133 }
134}

References BENCH_REPORT::charAcc, and BENCH_REPORT::linesRead.

◆ bench_line_reader_reuse()

template<typename LR >
static void bench_line_reader_reuse ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using a given LINE_READER implementation.

The LINE_READER is rewound for each cycle, not recreated.

Definition at line 142 of file io_benchmark.cpp.

143{
144 LR fstr( aFile.GetFullPath() );
145 for( int i = 0; i < aReps; ++i)
146 {
147
148 while( fstr.ReadLine() )
149 {
150 report.linesRead++;
151 report.charAcc += (unsigned char) fstr.Line()[0];
152 }
153
154 fstr.Rewind();
155 }
156}

References BENCH_REPORT::charAcc, and BENCH_REPORT::linesRead.

◆ bench_string_lr()

static void bench_string_lr ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using STRING_LINE_READER on string data read into memory from a file using std::ifstream, but read the data fresh from the file each time.

Definition at line 163 of file io_benchmark.cpp.

164{
165 for( int i = 0; i < aReps; ++i)
166 {
167 std::ifstream ifs( aFile.GetFullPath().ToStdString() );
168 std::string content((std::istreambuf_iterator<char>(ifs)),
169 std::istreambuf_iterator<char>());
170
171 STRING_LINE_READER fstr( content, aFile.GetFullPath() );
172 while( fstr.ReadLine() )
173 {
174 report.linesRead++;
175 report.charAcc += (unsigned char) fstr.Line()[0];
176 }
177 }
178}
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:241

References BENCH_REPORT::charAcc, LINE_READER::Line(), BENCH_REPORT::linesRead, and STRING_LINE_READER::ReadLine().

◆ bench_string_lr_reuse()

static void bench_string_lr_reuse ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using STRING_LINE_READER on string data read into memory from a file using std::ifstream.

The STRING_LINE_READER is not reused (it cannot be rewound), but the file is read only once

Definition at line 188 of file io_benchmark.cpp.

189{
190 std::ifstream ifs( aFile.GetFullPath().ToStdString() );
191 std::string content((std::istreambuf_iterator<char>(ifs)),
192 std::istreambuf_iterator<char>());
193
194 for( int i = 0; i < aReps; ++i)
195 {
196 STRING_LINE_READER fstr( content, aFile.GetFullPath() );
197 while( fstr.ReadLine() )
198 {
199 report.linesRead++;
200 report.charAcc += (unsigned char) fstr.Line()[0];
201 }
202 }
203}

References BENCH_REPORT::charAcc, LINE_READER::Line(), BENCH_REPORT::linesRead, and STRING_LINE_READER::ReadLine().

◆ bench_wxbis()

template<typename WXIS >
static void bench_wxbis ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using a INPUTSTREAM_LINE_READER with a given wxInputStream implementation, buffered with wxBufferedInputStream.

The wxInputStream is recreated for each cycle.

Definition at line 261 of file io_benchmark.cpp.

262{
263 WXIS fileStream( aFile.GetFullPath() );
264 wxBufferedInputStream bufferedStream( fileStream );
265
266 for( int i = 0; i < aReps; ++i)
267 {
268 INPUTSTREAM_LINE_READER istr( &bufferedStream, aFile.GetFullPath() );
269
270 while( istr.ReadLine() )
271 {
272 report.linesRead++;
273 report.charAcc += (unsigned char) istr.Line()[0];
274 }
275
276 fileStream.SeekI( 0 );
277 }
278}
A LINE_READER that reads from a wxInputStream object.
Definition: richio.h:275

References BENCH_REPORT::charAcc, LINE_READER::Line(), BENCH_REPORT::linesRead, and INPUTSTREAM_LINE_READER::ReadLine().

◆ bench_wxbis_reuse()

template<typename WXIS >
static void bench_wxbis_reuse ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using a INPUTSTREAM_LINE_READER with a given wxInputStream implementation, buffered with wxBufferedInputStream.

The wxInputStream is reset for each cycle.

Definition at line 287 of file io_benchmark.cpp.

288{
289 WXIS fileStream( aFile.GetFullPath() );
290 wxBufferedInputStream bufferedStream( fileStream );
291
292 INPUTSTREAM_LINE_READER istr( &bufferedStream, aFile.GetFullPath() );
293
294 for( int i = 0; i < aReps; ++i)
295 {
296 while( istr.ReadLine() )
297 {
298 report.linesRead++;
299 report.charAcc += (unsigned char) istr.Line()[0];
300 }
301
302 fileStream.SeekI( 0 );
303 }
304}

References BENCH_REPORT::charAcc, LINE_READER::Line(), BENCH_REPORT::linesRead, and INPUTSTREAM_LINE_READER::ReadLine().

◆ bench_wxis()

template<typename S >
static void bench_wxis ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using an INPUTSTREAM_LINE_READER with a given wxInputStream implementation.

The wxInputStream is recreated for each cycle.

Definition at line 212 of file io_benchmark.cpp.

213{
214 S fileStream( aFile.GetFullPath() );
215
216 for( int i = 0; i < aReps; ++i)
217 {
218 INPUTSTREAM_LINE_READER istr( &fileStream, aFile.GetFullPath() );
219
220 while( istr.ReadLine() )
221 {
222 report.linesRead++;
223 report.charAcc += (unsigned char) istr.Line()[0];
224 }
225
226 fileStream.SeekI( 0 );
227 }
228}

References BENCH_REPORT::charAcc, LINE_READER::Line(), BENCH_REPORT::linesRead, and INPUTSTREAM_LINE_READER::ReadLine().

◆ bench_wxis_reuse()

template<typename S >
static void bench_wxis_reuse ( const wxFileName &  aFile,
int  aReps,
BENCH_REPORT report 
)
static

Benchmark using an INPUTSTREAM_LINE_READER with a given wxInputStream implementation.

The wxInputStream is reset for each cycle.

Definition at line 237 of file io_benchmark.cpp.

238{
239 S fileStream( aFile.GetFullPath() );
240 INPUTSTREAM_LINE_READER istr( &fileStream, aFile.GetFullPath() );
241
242 for( int i = 0; i < aReps; ++i)
243 {
244 while( istr.ReadLine() )
245 {
246 report.linesRead++;
247 report.charAcc += (unsigned char) istr.Line()[0];
248 }
249
250 fileStream.SeekI( 0 );
251 }
252}

References BENCH_REPORT::charAcc, LINE_READER::Line(), BENCH_REPORT::linesRead, and INPUTSTREAM_LINE_READER::ReadLine().

◆ executeBenchMark()

BENCH_REPORT executeBenchMark ( const BENCHMARK aBenchmark,
int  aReps,
const wxFileName &  aFilename 
)

Definition at line 363 of file io_benchmark.cpp.

365{
366 BENCH_REPORT report = {};
367
368 TIME_PT start = CLOCK::now();
369 aBenchmark.func( aFilename, aReps, report );
370 TIME_PT end = CLOCK::now();
371
372 using std::chrono::milliseconds;
373 using std::chrono::duration_cast;
374
375 report.benchDurMs = duration_cast<milliseconds>( end - start );
376
377 return report;
378}
std::chrono::time_point< CLOCK > TIME_PT
BENCH_FUNC func
std::chrono::milliseconds benchDurMs

References BENCH_REPORT::benchDurMs, and BENCHMARK::func.

Referenced by io_benchmark_func().

◆ getBenchDescriptions()

static wxString getBenchDescriptions ( )
static

Usage description of a benchmakr spec.

Definition at line 350 of file io_benchmark.cpp.

351{
352 wxString desc;
353
354 for( auto& bmark : benchmarkList )
355 {
356 desc << " " << bmark.triggerChar << ": " << bmark.name << "\n";
357 }
358
359 return desc;
360}
static std::vector< BENCHMARK > benchmarkList
List of available benchmarks.

References benchmarkList.

Referenced by io_benchmark_func().

◆ getBenchFlags()

static wxString getBenchFlags ( )
static

Construct string of all flags used for specifying benchmarks on the command line.

Definition at line 334 of file io_benchmark.cpp.

335{
336 wxString flags;
337
338 for( auto& bmark : benchmarkList )
339 {
340 flags << bmark.triggerChar;
341 }
342
343 return flags;
344}

References benchmarkList.

Referenced by io_benchmark_func().

◆ io_benchmark_func()

int io_benchmark_func ( int  argc,
char *  argv[] 
)

Definition at line 381 of file io_benchmark.cpp.

382{
383 auto& os = std::cout;
384
385 if (argc < 3)
386 {
387 os << "Usage: " << argv[0] << " <FILE> <REPS> [" << getBenchFlags() << "]\n\n";
388 os << "Benchmarks:\n";
389 os << getBenchDescriptions();
391 }
392
393 wxFileName inFile( argv[1] );
394
395 long reps = 0;
396 wxString( argv[2] ).ToLong( &reps );
397
398 // get the benchmark to do, or all of them if nothing given
399 wxString bench;
400 if ( argc == 4 )
401 bench = argv[3];
402
403 os << "IO Bench Mark Util" << std::endl;
404
405 os << " Benchmark file: " << inFile.GetFullPath() << std::endl;
406 os << " Repetitions: " << (int) reps << std::endl;
407 os << std::endl;
408
409 for( auto& bmark : benchmarkList )
410 {
411 if( bench.size() && !bench.Contains( bmark.triggerChar ) )
412 continue;
413
414 BENCH_REPORT report = executeBenchMark( bmark, reps, inFile );
415
416 os << wxString::Format( "%-30s %u lines, acc: %u in %u ms",
417 bmark.name, report.linesRead, report.charAcc, (int) report.benchDurMs.count() )
418 << std::endl;;
419 }
420
422}
#define OK
static wxString getBenchFlags()
Construct string of all flags used for specifying benchmarks on the command line.
BENCH_REPORT executeBenchMark(const BENCHMARK &aBenchmark, int aReps, const wxFileName &aFilename)
static wxString getBenchDescriptions()
Usage description of a benchmakr spec.
@ BAD_CMDLINE
The command line was not correct for the tool.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200

References KI_TEST::BAD_CMDLINE, BENCH_REPORT::benchDurMs, benchmarkList, BENCH_REPORT::charAcc, executeBenchMark(), Format(), getBenchDescriptions(), getBenchFlags(), BENCH_REPORT::linesRead, and OK.

Variable Documentation

◆ benchmarkList

std::vector<BENCHMARK> benchmarkList
static
Initial value:
=
{
{ 'f', bench_fstream, "std::fstream" },
{ 'F', bench_fstream_reuse, "std::fstream, reused" },
{ 'r', bench_line_reader<FILE_LINE_READER>, "RichIO FILE_L_R" },
{ 'R', bench_line_reader_reuse<FILE_LINE_READER>, "RichIO FILE_L_R, reused" },
{ 'n', bench_line_reader<IFSTREAM_LINE_READER>, "std::ifstream L_R" },
{ 'N', bench_line_reader_reuse<IFSTREAM_LINE_READER>, "std::ifstream L_R, reused" },
{ 's', bench_string_lr, "RichIO STRING_L_R"},
{ 'S', bench_string_lr_reuse, "RichIO STRING_L_R, reused"},
{ 'w', bench_wxis<wxFileInputStream>, "wxFileIStream" },
{ 'W', bench_wxis<wxFileInputStream>, "wxFileIStream, reused" },
{ 'g', bench_wxis<wxFFileInputStream>, "wxFFileIStream" },
{ 'G', bench_wxis_reuse<wxFFileInputStream>, "wxFFileIStream, reused" },
{ 'b', bench_wxbis<wxFileInputStream>, "wxFileIStream. buf'd" },
{ 'B', bench_wxbis_reuse<wxFileInputStream>, "wxFileIStream, buf'd, reused" },
{ 'c', bench_wxbis<wxFFileInputStream>, "wxFFileIStream. buf'd" },
{ 'C', bench_wxbis_reuse<wxFFileInputStream>, "wxFFileIStream, buf'd, reused" },
}
static void bench_fstream_reuse(const wxFileName &aFile, int aReps, BENCH_REPORT &report)
Benchmark using a raw std::ifstream, with no LINE_READER wrapper.
static void bench_string_lr_reuse(const wxFileName &aFile, int aReps, BENCH_REPORT &report)
Benchmark using STRING_LINE_READER on string data read into memory from a file using std::ifstream.
static void bench_string_lr(const wxFileName &aFile, int aReps, BENCH_REPORT &report)
Benchmark using STRING_LINE_READER on string data read into memory from a file using std::ifstream,...
static void bench_fstream(const wxFileName &aFile, int aReps, BENCH_REPORT &report)
Benchmark using a raw std::ifstream, with no LINE_READER wrapper.

List of available benchmarks.

Definition at line 309 of file io_benchmark.cpp.

Referenced by getBenchDescriptions(), getBenchFlags(), and io_benchmark_func().

◆ registered

bool registered
static
Initial value:
"io_benchmark",
"Benchmark various kinds of IO methods",
} )
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
int io_benchmark_func(int argc, char *argv[])

Definition at line 425 of file io_benchmark.cpp.