diff options
Diffstat (limited to 'EASTL/benchmark/source/EASTLBenchmark.h')
-rw-r--r-- | EASTL/benchmark/source/EASTLBenchmark.h | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/EASTL/benchmark/source/EASTLBenchmark.h b/EASTL/benchmark/source/EASTLBenchmark.h new file mode 100644 index 0000000..a0833e6 --- /dev/null +++ b/EASTL/benchmark/source/EASTLBenchmark.h @@ -0,0 +1,228 @@ +///////////////////////////////////////////////////////////////////////////// +// Copyright (c) Electronic Arts Inc. All rights reserved. +///////////////////////////////////////////////////////////////////////////// + + +#ifndef EASTLBENCHMARK_H +#define EASTLBENCHMARK_H + + +// Intrinsic control +// +// Our benchmark results are being skewed by inconsistent decisions by the +// VC++ compiler to use intrinsic functions. Additionally, many of our +// benchmarks work on large blocks of elements, whereas intrinsics often +// are an improvement only over small blocks of elements. As a result, +// enabling of intrinsics is often resulting in poor benchmark results for +// code that gets an intrinsic enabled for it, even though it will often +// happen in real code to be the opposite case. The disabling of intrinsics +// here often results in EASTL performance being lower than it would be in +// real-world situations. +// +#include <string.h> +#ifdef _MSC_VER + #pragma function(strlen, strcmp, strcpy, strcat, memcpy, memcmp, memset) +#endif + + +#include <EASTL/set.h> +#include <EASTL/string.h> +#include <EAStdC/EAStopwatch.h> +#include <stdlib.h> +#include <string.h> + + +void BenchmarkSort(); +void BenchmarkList(); +void BenchmarkString(); +void BenchmarkVector(); +void BenchmarkDeque(); +void BenchmarkSet(); +void BenchmarkMap(); +void BenchmarkHash(); +void BenchmarkAlgorithm(); +void BenchmarkHeap(); +void BenchmarkBitset(); +void BenchmarkTupleVector(); + + +namespace Benchmark +{ + + // Environment + // + // The environment for this benchmark test. + // + struct Environment + { + eastl::string8 msPlatform; // Name of test platform (e.g. "Windows") + eastl::string8 msSTLName1; // Name of competitor #1 (e.g. "EASTL"). + eastl::string8 msSTLName2; // Name of competitor #2 (e.g. "MS STL"). + + void clear() { msPlatform.set_capacity(0); msSTLName1.set_capacity(0); msSTLName2.set_capacity(0); } + }; + + Environment& GetEnvironment(); + + + // Result + // + // An individual benchmark result. + // + struct Result + { + eastl::string8 msName; // Test name (e.g. "vector/insert"). + int mUnits; // Timing units (e.g. EA::StdC::Stopwatch::kUnitsSeconds). + int64_t mTime1; // Time of competitor #1. + uint64_t mTime1NS; // Nanoseconds. + int64_t mTime2; // Time of competitor #2. + int64_t mTime2NS; // Nanoseconds. + eastl::string8 msNotes; // Any comments to attach to this result. + + Result() : msName(), mUnits(EA::StdC::Stopwatch::kUnitsCPUCycles), + mTime1(0), mTime1NS(0), mTime2(0), mTime2NS(0), msNotes() { } + }; + + inline bool operator<(const Result& r1, const Result& r2) + { return r1.msName < r2.msName; } + + typedef eastl::set<Result> ResultSet; + + ResultSet& GetResultSet(); + + + // Scratch sprintf buffer + extern char gScratchBuffer[1024]; + + + + // Utility functions + // + void DoNothing(...); + void AddResult(const char* pName, int units, int64_t nTime1, int64_t nTime2, const char* pNotes = NULL); + void PrintResults(); + void WriteTime(int64_t timeNS, eastl::string& sTime); + + +} // namespace Benchmark + + + + +/////////////////////////////////////////////////////////////////////////////// +/// LargePOD +/// +/// Implements a structure which is essentially a largish POD. Useful for testing +/// containers and algorithms for their ability to efficiently work with PODs. +/// This class isn't strictly a POD by the definition of the C++ standard, +/// but it suffices for our interests. +/// +struct LargeObject +{ + int32_t mData[2048]; +}; + +struct LargePOD +{ + LargeObject mLargeObject1; + LargeObject mLargeObject2; + const char* mpName1; + const char* mpName2; + + explicit LargePOD(int32_t x = 0) // A true POD doesn't have a non-trivial constructor. + { + memset(mLargeObject1.mData, 0, sizeof(mLargeObject1.mData)); + memset(mLargeObject2.mData, 0, sizeof(mLargeObject2.mData)); + mLargeObject1.mData[0] = x; + + mpName1 = "LargePOD1"; + mpName2 = "LargePOD2"; + } + + LargePOD(const LargePOD& largePOD) // A true POD doesn't have a non-trivial copy-constructor. + : mLargeObject1(largePOD.mLargeObject1), + mLargeObject2(largePOD.mLargeObject2), + mpName1(largePOD.mpName1), + mpName2(largePOD.mpName2) + { + } + + virtual ~LargePOD() { } + + LargePOD& operator=(const LargePOD& largePOD) // A true POD doesn't have a non-trivial assignment operator. + { + if(&largePOD != this) + { + mLargeObject1 = largePOD.mLargeObject1; + mLargeObject2 = largePOD.mLargeObject2; + mpName1 = largePOD.mpName1; + mpName2 = largePOD.mpName2; + } + return *this; + } + + virtual void DoSomething() // Note that by declaring this virtual, this class is not truly a POD. + { // But it acts like a POD for the purposes of EASTL algorithms. + mLargeObject1.mData[1]++; + } + + operator int() + { + return (int)mLargeObject1.mData[0]; + } +}; + +//EASTL_DECLARE_POD(LargePOD); +//EASTL_DECLARE_TRIVIAL_CONSTRUCTOR(LargePOD); +//EASTL_DECLARE_TRIVIAL_COPY(LargePOD); +//EASTL_DECLARE_TRIVIAL_ASSIGN(LargePOD); +//EASTL_DECLARE_TRIVIAL_DESTRUCTOR(LargePOD); +//EASTL_DECLARE_TRIVIAL_RELOCATE(LargePOD); + +// Operators +// We specifically define only == and <, in order to verify that +// our containers and algorithms are not mistakenly expecting other +// operators for the contained and manipulated classes. +inline bool operator==(const LargePOD& t1, const LargePOD& t2) +{ + return (memcmp(&t1.mLargeObject1, &t2.mLargeObject1, sizeof(t1.mLargeObject1)) == 0) && + (memcmp(&t1.mLargeObject2, &t2.mLargeObject2, sizeof(t1.mLargeObject2)) == 0) && + (strcmp(t1.mpName1, t2.mpName1) == 0) && + (strcmp(t1.mpName2, t2.mpName2) == 0); +} + +inline bool operator<(const LargePOD& t1, const LargePOD& t2) +{ + return (memcmp(&t1.mLargeObject1, &t2.mLargeObject1, sizeof(t1.mLargeObject1)) < 0) && + (memcmp(&t1.mLargeObject2, &t2.mLargeObject2, sizeof(t1.mLargeObject2)) < 0) && + (strcmp(t1.mpName1, t2.mpName1) < 0) && + (strcmp(t1.mpName2, t2.mpName2) < 0); +} + + + + + +#endif // Header sentry + + + + + + + + + + + + + + + + + + + + + + |