From 99de5312e6e8c5ff10a4db5697f9987de2229670 Mon Sep 17 00:00:00 2001 From: "miloyip@gmail.com" Date: Tue, 22 Nov 2011 05:07:29 +0000 Subject: [PATCH] Separated platform related performance tests from rapidjsontest Added multiple platform specific file I/O performance tests Added CheckSum() in platform test as baseline of parsing speed, which should be more appropriate than strlen(). git-svn-id: https://rapidjson.googlecode.com/svn/trunk@26 c5894555-1306-4e8d-425f-1f6f381ee07c --- test/perftest/platformtest.cpp | 152 ++++++++++++++++++++++++++++++++ test/perftest/rapidjsontest.cpp | 47 +--------- test/perftest/yajltest.cpp | 4 +- test/unittest/documenttest.cpp | 2 + 4 files changed, 159 insertions(+), 46 deletions(-) create mode 100644 test/perftest/platformtest.cpp diff --git a/test/perftest/platformtest.cpp b/test/perftest/platformtest.cpp new file mode 100644 index 0000000..ca23b2c --- /dev/null +++ b/test/perftest/platformtest.cpp @@ -0,0 +1,152 @@ +#include "perftest.h" + +// This file is for giving the performance characteristics of the platform (compiler/OS/CPU). + +#if TEST_PLATFORM + +#include +#include + +// Windows +#ifdef _WIN32 +#include +#endif + +// UNIX +#if defined(unix) || defined(__unix__) || defined(__unix) +#include +#ifdef _POSIX_MAPPED_FILES +#include +#endif +#endif + +class Platform : public PerfTest { +public: + virtual void SetUp() { + PerfTest::SetUp(); + + // temp buffer for testing + temp_ = (char *)malloc(length_ + 1); + memcpy(temp_, json_, length_); + checkSum_ = CheckSum(); + } + + char CheckSum() { + char c = 0; + for (size_t i = 0; i < length_; ++i) + c += temp_[i]; + return c; + } + + virtual void TearDown() { + PerfTest::TearDown(); + free(temp_); + } + +protected: + char *temp_; + char checkSum_; +}; + +TEST_F(Platform, CheckSum) { + for (int i = 0; i < kTrialCount; i++) + EXPECT_EQ(checkSum_, CheckSum()); +} + +TEST_F(Platform, strlen) { + for (int i = 0; i < kTrialCount; i++) { + size_t l = strlen(json_); + EXPECT_EQ(length_, l); + } +} + +TEST_F(Platform, memcmp) { + for (int i = 0; i < kTrialCount; i++) { + EXPECT_EQ(0, memcmp(temp_, json_, length_)); + } +} + +TEST_F(Platform, pow) { + double sum = 0; + for (int i = 0; i < kTrialCount * kTrialCount; i++) + sum += pow(10.0, i & 255); + EXPECT_GT(sum, 0.0); +} + +TEST_F(Platform, Whitespace_strlen) { + for (int i = 0; i < kTrialCount; i++) { + size_t l = strlen(whitespace_); + EXPECT_GT(l, whitespace_length_); + } +} + +TEST_F(Platform, Whitespace_strspn) { + for (int i = 0; i < kTrialCount; i++) { + size_t l = strspn(whitespace_, " \n\r\t"); + EXPECT_EQ(whitespace_length_, l); + } +} + +TEST_F(Platform, fread) { + for (int i = 0; i < kTrialCount; i++) { + FILE *fp = fopen(filename_, "rb"); + ASSERT_EQ(length_, fread(temp_, 1, length_, fp)); + EXPECT_EQ(checkSum_, CheckSum()); + fclose(fp); + } +} + +#ifdef _MSC_VER +TEST_F(Platform, read) { + for (int i = 0; i < kTrialCount; i++) { + int fd = _open(filename_, _O_BINARY | _O_RDONLY); + ASSERT_NE(-1, fd); + ASSERT_EQ(length_, _read(fd, temp_, length_)); + EXPECT_EQ(checkSum_, CheckSum()); + _close(fd); + } +} +#else +TEST_F(Platform, read) { + for (int i = 0; i < kTrialCount; i++) { + int fd = open(filename_, O_BINARY | O_RDONLY); + ASSERT_NE(-1, fd); + ASSERT_EQ(length_, read(fd, temp_, length_)); + EXPECT_EQ(checkSum_, CheckSum()); + close(fd); + } +} +#endif + +#ifdef _WIN32 +TEST_F(Platform, MapViewOfFile) { + for (int i = 0; i < kTrialCount; i++) { + HANDLE file = CreateFile(filename_, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, file); + HANDLE mapObject = CreateFileMapping(file, NULL, PAGE_READONLY, 0, length_, NULL); + ASSERT_NE(INVALID_HANDLE_VALUE, mapObject); + void *p = MapViewOfFile(mapObject, FILE_MAP_READ, 0, 0, length_); + ASSERT_TRUE(p != NULL); + EXPECT_EQ(checkSum_, CheckSum()); + ASSERT_TRUE(UnmapViewOfFile(p) == TRUE); + ASSERT_TRUE(CloseHandle(mapObject) == TRUE); + ASSERT_TRUE(CloseHandle(file) == TRUE); + } +} +#endif + +#ifdef _POSIX_MAPPED_FILES +TEST_F(Platform, mmap) { + for (int i = 0; i < kTrialCount; i++) { + int fd = open(filename_, _O_BINARY | _O_RDONLY); + ASSERT_NE(-1, fd); + void *p = mmap(NULL, length_, PROT_READ, MAP_PRIVATE, fd, 0); + ASSERT_TRUE(p != NULL); + EXPECT_EQ(checkSum_, CheckSum()); + munmap(p, length_); + close(fd); + } +} +#endif + +#endif // TEST_PLATFORM diff --git a/test/perftest/rapidjsontest.cpp b/test/perftest/rapidjsontest.cpp index fbf22f7..805ed20 100644 --- a/test/perftest/rapidjsontest.cpp +++ b/test/perftest/rapidjsontest.cpp @@ -8,7 +8,6 @@ #include "rapidjson/stringbuffer.h" #include "rapidjson/filestream.h" #include "rapidjson/filereadstream.h" -#include #ifdef RAPIDJSON_SSE2 #define SIMD_SUFFIX(name) name##_SSE2 @@ -42,16 +41,9 @@ protected: Document doc_; }; -TEST_F(RapidJson, strlen) { - for (int i = 0; i < kTrialCount; i++) { - size_t l = strlen(json_); - EXPECT_EQ(length_, l + 1); - } -} - TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_NullHandler)) { for (int i = 0; i < kTrialCount; i++) { - memcpy(temp_, json_, length_); + memcpy(temp_, json_, length_ + 1); InsituStringStream s(temp_); BaseReaderHandler<> h; Reader reader; @@ -73,7 +65,7 @@ TEST_F(RapidJson, SIMD_SUFFIX(DoucmentParseInsitu_MemoryPoolAllocator)) { //char* userBuffer = (char*)malloc(userBufferSize); for (int i = 0; i < kTrialCount; i++) { - memcpy(temp_, json_, length_); + memcpy(temp_, json_, length_ + 1); //MemoryPoolAllocator<> allocator(userBuffer, userBufferSize); //Document doc(&allocator); Document doc; @@ -115,7 +107,7 @@ TEST_F(RapidJson, SIMD_SUFFIX(DoucmentParse_MemoryPoolAllocator)) { TEST_F(RapidJson, SIMD_SUFFIX(DoucmentParse_CrtAllocator)) { for (int i = 0; i < kTrialCount; i++) { - memcpy(temp_, json_, length_); + memcpy(temp_, json_, length_ + 1); GenericDocument, CrtAllocator> doc; doc.Parse<0>(temp_); ASSERT_TRUE(doc.IsObject()); @@ -206,13 +198,6 @@ TEST_F(RapidJson, PrettyWriter_StringBuffer) { } } -TEST_F(RapidJson, pow) { - double sum = 0; - for (int i = 0; i < kTrialCount * kTrialCount; i++) - sum += pow(10.0, i & 255); - EXPECT_GT(sum, 0.0); -} - TEST_F(RapidJson, internal_Pow10) { double sum = 0; for (int i = 0; i < kTrialCount * kTrialCount; i++) @@ -220,20 +205,6 @@ TEST_F(RapidJson, internal_Pow10) { EXPECT_GT(sum, 0.0); } -TEST_F(RapidJson, Whitespace_strlen) { - for (int i = 0; i < kTrialCount; i++) { - size_t l = strlen(whitespace_); - EXPECT_GT(l, whitespace_length_); - } -} - -TEST_F(RapidJson, Whitespace_strspn) { - for (int i = 0; i < kTrialCount; i++) { - size_t l = strspn(whitespace_, " \n\r\t"); - EXPECT_EQ(whitespace_length_, l); - } -} - TEST_F(RapidJson, SIMD_SUFFIX(Whitespace)) { for (int i = 0; i < kTrialCount; i++) { Document doc; @@ -241,18 +212,6 @@ TEST_F(RapidJson, SIMD_SUFFIX(Whitespace)) { } } - -TEST_F(RapidJson, fread) { - for (int i = 0; i < kTrialCount; i++) { - FILE *fp = fopen(filename_, "rb"); - fread(temp_, 1, length_, fp); - temp_[length_] = '\0'; - for (char *p = temp_; *p; ++p) - ; - fclose(fp); - } -} - // Depreciated. //TEST_F(RapidJson, FileStream_Read) { // for (int i = 0; i < kTrialCount; i++) { diff --git a/test/perftest/yajltest.cpp b/test/perftest/yajltest.cpp index af6892b..d8869ad 100644 --- a/test/perftest/yajltest.cpp +++ b/test/perftest/yajltest.cpp @@ -53,10 +53,10 @@ static yajl_callbacks nullcallbacks = { TEST_F(Yajl, yajl_parse_nullcallbacks) { for (int i = 0; i < kTrialCount; i++) { yajl_handle hand = yajl_alloc(&nullcallbacks, NULL, NULL); - yajl_status stat = yajl_parse(hand, (unsigned char*)json_, length_ - 1); + yajl_status stat = yajl_parse(hand, (unsigned char*)json_, length_); //ASSERT_EQ(yajl_status_ok, stat); if (stat != yajl_status_ok) { - unsigned char * str = yajl_get_error(hand, 1, (unsigned char*)json_, length_ + 1); + unsigned char * str = yajl_get_error(hand, 1, (unsigned char*)json_, length_); fprintf(stderr, "%s", (const char *) str); } stat = yajl_complete_parse(hand); diff --git a/test/unittest/documenttest.cpp b/test/unittest/documenttest.cpp index 57dbfb6..9a4dcef 100644 --- a/test/unittest/documenttest.cpp +++ b/test/unittest/documenttest.cpp @@ -47,12 +47,14 @@ TEST(Document, Parse) { EXPECT_EQ(i + 1, a[i].GetUint()); } +// This should be slow due to assignment in inner-loop. struct OutputStringStream : public std::ostringstream { typedef char Ch; void Put(char c) { put(c); } + void Flush() {} }; TEST(Document, AcceptWriter) {