From ef6957c177bd6d971bfedfbfe656c4b82d71f9a3 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Thu, 31 Dec 2015 15:30:28 +0800 Subject: [PATCH] PutReserve() and PutUnsafe() optimisation for Writer --- .gitignore | 1 + bin/types/booleans.json | Bin 0 -> 849 bytes bin/types/floats.json | Bin 0 -> 1698 bytes bin/types/guids.json | Bin 0 -> 4202 bytes bin/types/integers.json | Bin 0 -> 1098 bytes bin/types/mixed.json | Bin 0 -> 15142 bytes bin/types/nulls.json | Bin 0 -> 802 bytes bin/types/paragraphs.json | Bin 0 -> 33764 bytes bin/types/readme.txt | 1 + include/rapidjson/encodings.h | 77 +++++++++++++++++++ include/rapidjson/internal/stack.h | 12 ++- include/rapidjson/rapidjson.h | 16 +++- include/rapidjson/stringbuffer.h | 13 ++++ include/rapidjson/writer.h | 79 +++++++++++--------- test/perftest/perftest.h | 114 ++++++++++++++++++++--------- test/perftest/rapidjsontest.cpp | 29 +++++++- 16 files changed, 272 insertions(+), 70 deletions(-) create mode 100755 bin/types/booleans.json create mode 100755 bin/types/floats.json create mode 100755 bin/types/guids.json create mode 100755 bin/types/integers.json create mode 100755 bin/types/mixed.json create mode 100755 bin/types/nulls.json create mode 100755 bin/types/paragraphs.json create mode 100644 bin/types/readme.txt diff --git a/.gitignore b/.gitignore index d97a316..2c412c2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ !/bin/data !/bin/encodings !/bin/jsonchecker +!/bin/types /build /doc/html /doc/doxygen_*.db diff --git a/bin/types/booleans.json b/bin/types/booleans.json new file mode 100755 index 0000000000000000000000000000000000000000..2dcbb5fe8765a18916d8f6d517dd0e24d479c250 GIT binary patch literal 849 zcmcJJI|_g>5JdZ&A_wqBVqu|`m7n_y!W%RL30bh3$?V(Nj49`Hzn0;p>%1LLAX5^& z1;|7u9m`fvP^voJfNElaO(0sTMHw~}xB)>$5TG`&01_48rUNmQAgcbGO7g=IDg#%2 Ie;c+jrNsOx;^!tf0}ci_*lfvq1`LGr%U_> zoSa3H+4G91@0BGYd)G~(n#;shxa1dyN-eP*^OC+$tCv|QbzE;iPBY`<{mT3{b@#-S zP2L-`bfV2eZ!fi%dP^siobOI+u|)uP&p$QcMVgK2&F~{Ip&@kq0t!KuaA9p1*N-!N zRY=_=W-F}poF9RE7WKF6@b|!V!HkUc6X7?xq|J8aOQABWO!lvhG!Z5bu#uM~P**dl^wjlU;?tHk&xVNY5z<)XVXvS{ha6KJ>>$+` zSldrJ8+yZIk&oqLC}^|)MUX`?tfKNcj^4Ec4N7mx(ONDI|qY&lxtvYw2gTve~E5}HIVZ$&a^mEJGj1a+USPmM4kiyAKT(#avM#78igu- zFviv>dL`Vwl!}Yz4A5%lX&Schr#Zl$gaH?ww%hv_MPr9NfOa@($7vT?%yC-Vz zNap7TM3+iXmN9<;*s_heApJt;^V+)0aQ=G(b_TYyGG2G1tRpz~Z$Op09SnayR z(srGt=E~~~IbSF=*S#YceKlqtW9AUSg*z3iShIIv+lzo&z;o&}yaRNe?CD{WRK Z({KVx*$F6S%YS8$Mc5mPY5x5C=Rb9MGfe;h literal 0 HcmV?d00001 diff --git a/bin/types/guids.json b/bin/types/guids.json new file mode 100755 index 0000000000000000000000000000000000000000..9d7f5dbc8f9e0a8fcb6748412300c0c73b3e06c0 GIT binary patch literal 4202 zcmX|^NshEB4ug-!0L)G< zy7UCusRygG1Y5(;YQ5&x{`t?Jl`b*&E@5wPL0a)JhPE)J>J(Y()xMS4@|F}+@OpBP z=o+-w7gyC#vs;bP}Lb? z^XhBNJ=b{#J6cUEC~m zoAuUi!L*Ffe9W^o*WTn?>0*1PG(z=g+*4-oq8d^hn%Wf2_G;g8pE%t^%AJ*#H4LQ- zwM%lzqvrlrt{Ss8t6_Sl^KwL9yNF1DblFcA_uV8~G(EWqL!MzJ!d;3)i{C{ znkw58{Zz2jT0bDPw*C4!&1reeVa>IINR{Ae#L$+dEJJ!3ulB5Er8*|>o;Y1=3r;1W z#yWD%+bq46Nm{CXw$QV&GFDC>Bhj?Bt#v6&-#u-gb}|U*CBhD0nH!(Z>9xh`bF7fWMjSfN% zy^)?u7-z@8qSfM>I*xuT`&Re@!DA8Lh(f|BL&KzfvF$!ae|$fA`>A$9s}MuZ*}3CiABu zkfMOW9FpEQ8WYq}O{g||U&lEA?U{?xUk$}(T>8Xw=yGcWOnk^BTBmgk@J}Aay9+Y7Z6hI-tdm~+EZBH#^Q7W>G>Kz>+BMRWr zt`2^kx3~qQ$50$NOWKOaRMZu&pFM3)6amafNqX z=+2qcwL1!fay1wdp zNX{8W=$OG=8+k~ONh6)j%MW<+w({$IK1WNm5-MEhbVb1u?C`Y~9OP%beo~|Q2Abzw zolmz*!+MDQAPy}b`C&fqlwG9-_T_Y#$Q#j5lcF*JTG1fEJ3+rS- zs!{gy?ny5MORd)e=;soyDCS%{7n>6SJ3oZXD6P`;-7n^4&0vr>j9B{K=GN?Wsd?NZ zBG>cOyJtl@ts_ny!^ZrS$NFA#)nw)598hUc7ZrBca9(q7e0r( z;|J^RZSgruRDOJ)NYAECA$5dXF7))I9TKWnadPeX>8EUbb7s^Xjo`JfE+GJ6YD_#q zjVnHn>rE^E3_k5@NTf?6!A-@#212X$L$bCLfqO$gvCJDh(BxD3lRfyd(fhCVJngE_ zM7^Dr)gtKvWk5Y5xOGl{E7KS(MQyg#i^}UqhS=XEfb;-=dv54(6_vXsKy@+pRM*1k zC~Xr#UtSVG%K#RP>wh$P;q+tXNI!9%5+i2vYOkqyp?N^!>ij|#x#s0FF((ypz8^w} z8Yx}r!~$R(?}E#amyo*EZ@g*xFi&5q#=b+W1Ti@c9$gLDng7UH6M=XLahDn&i66hcG zUN+iHUK;7@=h_{~S6=&&Pv|FrL;DtL9qs(i;4gm9O>$$|yL z`0h!B-plz{aYvUXzdYhHB@LooYs>8+dGuw{QDOv+&J&2p^R$Z4ltibd^W)KI zxr2)Fcx>1m+JPl<++hHCNUlb`j{Wh@?0FhIVo^Yjn3ZDPJO7o+Ki&YznqZ(fptM4RrSdBxTr>gbz60;IDL2V`P&;00hWpY-5p z`gvSI`yvw?u1&BY1wjnFm06}W1EJ_gd`&yR{O^agwu^7!r2M!~QJm~ev}qWV)sWl$tZATRsokVO(5 zbulDuCL~6R#5;Ulf=7jZpmjt*R1pIi%o_-r@7!Vmiw~c~U|N$GU1U5ECq3w7ure6i zK>(0?d~Xak4i2x1*h+v+W$XLv<#yGK=Su=+8Y6tOzN`}@_ zsXa4ujnXNQOLd%|iT)*lK8VeKTsv=Ga|7o;ES46Hz_Iz{?P;VgmL6n~5K1^gBN*6_ m@XXlB=!1}brw=Owi$FQf)g{Qolk;b;Ae7Vy^5vhu{`Y@~_4(`o literal 0 HcmV?d00001 diff --git a/bin/types/integers.json b/bin/types/integers.json new file mode 100755 index 0000000000000000000000000000000000000000..5dd05e097a4f89220957e18bd013c58ab7e4b44f GIT binary patch literal 1098 zcmXw2$+25O2)zF&egHlI%^Hi#`KRF?kV*$pGrWdg=I_t%Z>vRi{(0p@m&_|;D$VSb z+B`RZWlgpZ_7qWmpQ*NM?7g(g)GIv^?B3Ie02a%v#IOKxYs8**&U|`Jx^NBEslb9& zguBZFGtm<0;!bPMBBb!w+pAqww+?K|Yd3Ecw6-BNI&E222htY|A{?>hWQfZuVoB<; zr(`LWTl#dnZ9|HqWy!ZB*IjO@0@EdL?G5a-rjj|!Vhj=28$&ofFx8}jk6U`FViADw zIL2OGu1je0aXv7&`0%mE=&YD5%y}7ZCzCqqo`1$`-D@LI#_2pl(Bo*8iI3~Vx`uu} zA47i=!dzBaDiPb9hGM=4XLbks?;d{*&f}P9bsxUat*Gcr;>&iRegGRH1Zmt zhEEuZ_A(@|A;iY>q-i(~0gMwfw+KT$FVT#X_@%`|TYW!!so+Mhmr3b3@#qd?w1k4U z9;+@Ad?}{`DcEVsf7*7EFmR320W`kuC1`QVe%4XpUsp8j3{*PJ{J$M?%3O|6wMBhw z0i(GM3<$$;xLiPQ8pBv}y#o*HOG7@lzH#c&1LG6syfgV5ob3(o3 literal 0 HcmV?d00001 diff --git a/bin/types/mixed.json b/bin/types/mixed.json new file mode 100755 index 0000000000000000000000000000000000000000..43e9a1d7be070f5eb75a3925f99a54b701b4c65b GIT binary patch literal 15142 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 a>RVy5&K2MF)3cB)rDfK6F6935pZ^DNFpARv literal 0 HcmV?d00001 diff --git a/bin/types/readme.txt b/bin/types/readme.txt new file mode 100644 index 0000000..da1dae6 --- /dev/null +++ b/bin/types/readme.txt @@ -0,0 +1 @@ +Test data obtained from https://github.com/xpol/lua-rapidjson/tree/master/performance diff --git a/include/rapidjson/encodings.h b/include/rapidjson/encodings.h index f37f9e1..cc676d8 100644 --- a/include/rapidjson/encodings.h +++ b/include/rapidjson/encodings.h @@ -120,6 +120,28 @@ struct UTF8 { } } + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + PutUnsafe(os, static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + PutUnsafe(os, static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + PutUnsafe(os, static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + } + template static bool Decode(InputStream& is, unsigned* codepoint) { #define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast(c) & 0x3Fu) @@ -261,6 +283,22 @@ struct UTF16 { } } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + PutUnsafe(os, static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + PutUnsafe(os, static_cast((v >> 10) | 0xD800)); + PutUnsafe(os, (v & 0x3FF) | 0xDC00); + } + } + template static bool Decode(InputStream& is, unsigned* codepoint) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); @@ -386,6 +424,13 @@ struct UTF32 { os.Put(codepoint); } + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, codepoint); + } + template static bool Decode(InputStream& is, unsigned* codepoint) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); @@ -501,6 +546,12 @@ struct ASCII { os.Put(static_cast(codepoint & 0xFF)); } + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + PutUnsafe(os, static_cast(codepoint & 0xFF)); + } + template static bool Decode(InputStream& is, unsigned* codepoint) { uint8_t c = static_cast(is.Take()); @@ -571,6 +622,13 @@ struct AutoUTF { (*f[os.GetType()])(os, codepoint); } + template + RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; + (*f[os.GetType()])(os, codepoint); + } + template RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) { typedef bool (*DecodeFunc)(InputStream&, unsigned*); @@ -604,6 +662,15 @@ struct Transcoder { return true; } + template + RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::EncodeUnsafe(os, codepoint); + return true; + } + //! Validate one Unicode codepoint from an encoded stream. template RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { @@ -611,6 +678,10 @@ struct Transcoder { } }; +// Forward declaration. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c); + //! Specialization of Transcoder with same source and target encoding. template struct Transcoder { @@ -620,6 +691,12 @@ struct Transcoder { return true; } + template + RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + template RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { return Encoding::Validate(is, os); // source/target encoding are the same diff --git a/include/rapidjson/internal/stack.h b/include/rapidjson/internal/stack.h index 5e5cda1..7c8294b 100644 --- a/include/rapidjson/internal/stack.h +++ b/include/rapidjson/internal/stack.h @@ -108,11 +108,21 @@ public: // Optimization note: try to minimize the size of this function for force inline. // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. template - RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { + RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { // Expand the stack if needed if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count >= stackEnd_)) Expand(count); + } + template + RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { + Reserve(count); + return PushUnsafe(count); + } + + template + RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { + RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count < stackEnd_); T* ret = reinterpret_cast(stackTop_); stackTop_ += sizeof(T) * count; return ret; diff --git a/include/rapidjson/rapidjson.h b/include/rapidjson/rapidjson.h index 0023abe..a90a4a0 100644 --- a/include/rapidjson/rapidjson.h +++ b/include/rapidjson/rapidjson.h @@ -614,11 +614,25 @@ struct StreamTraits { enum { copyOptimization = 0 }; }; +//! Reserve n characters for writing to a stream. +template +inline void PutReserve(Stream& stream, size_t count) { + (void)stream; + (void)count; +} + +//! Write character to a stream, presuming buffer is reserved. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { + stream.Put(c); +} + //! Put N copies of a character to a stream. template inline void PutN(Stream& stream, Ch c, size_t n) { + PutReserve(stream, n); for (size_t i = 0; i < n; i++) - stream.Put(c); + PutUnsafe(stream, c); } /////////////////////////////////////////////////////////////////////////////// diff --git a/include/rapidjson/stringbuffer.h b/include/rapidjson/stringbuffer.h index e9be849..40b51cd 100644 --- a/include/rapidjson/stringbuffer.h +++ b/include/rapidjson/stringbuffer.h @@ -48,6 +48,7 @@ public: #endif void Put(Ch c) { *stack_.template Push() = c; } + void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } void Flush() {} void Clear() { stack_.Clear(); } @@ -57,6 +58,8 @@ public: stack_.ShrinkToFit(); stack_.template Pop(1); } + + void Reserve(size_t count) { stack_.template Reserve(count); } Ch* Push(size_t count) { return stack_.template Push(count); } void Pop(size_t count) { stack_.template Pop(count); } @@ -82,6 +85,16 @@ private: //! String buffer with UTF8 encoding typedef GenericStringBuffer > StringBuffer; +template +inline void PutReserve(GenericStringBuffer& stream, size_t count) { + stream.Reserve(count); +} + +template +inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { + stream.PutUnsafe(c); +} + //! Implement specialized version of PutN() with memset() for better performance. template<> inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { diff --git a/include/rapidjson/writer.h b/include/rapidjson/writer.h index a450456..13db449 100644 --- a/include/rapidjson/writer.h +++ b/include/rapidjson/writer.h @@ -189,15 +189,18 @@ protected: static const size_t kDefaultLevelDepth = 32; bool WriteNull() { - os_->Put('n'); os_->Put('u'); os_->Put('l'); os_->Put('l'); return true; + PutReserve(*os_, 4); + PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true; } bool WriteBool(bool b) { if (b) { - os_->Put('t'); os_->Put('r'); os_->Put('u'); os_->Put('e'); + PutReserve(*os_, 4); + PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e'); } else { - os_->Put('f'); os_->Put('a'); os_->Put('l'); os_->Put('s'); os_->Put('e'); + PutReserve(*os_, 5); + PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e'); } return true; } @@ -205,40 +208,45 @@ protected: bool WriteInt(int i) { char buffer[11]; const char* end = internal::i32toa(i, buffer); + PutReserve(*os_, static_cast(end - buffer)); for (const char* p = buffer; p != end; ++p) - os_->Put(static_cast(*p)); + PutUnsafe(*os_, static_cast(*p)); return true; } bool WriteUint(unsigned u) { char buffer[10]; const char* end = internal::u32toa(u, buffer); + PutReserve(*os_, static_cast(end - buffer)); for (const char* p = buffer; p != end; ++p) - os_->Put(static_cast(*p)); + PutUnsafe(*os_, static_cast(*p)); return true; } bool WriteInt64(int64_t i64) { char buffer[21]; const char* end = internal::i64toa(i64, buffer); + PutReserve(*os_, static_cast(end - buffer)); for (const char* p = buffer; p != end; ++p) - os_->Put(static_cast(*p)); + PutUnsafe(*os_, static_cast(*p)); return true; } bool WriteUint64(uint64_t u64) { char buffer[20]; char* end = internal::u64toa(u64, buffer); + PutReserve(*os_, static_cast(end - buffer)); for (char* p = buffer; p != end; ++p) - os_->Put(static_cast(*p)); + PutUnsafe(*os_, static_cast(*p)); return true; } bool WriteDouble(double d) { char buffer[25]; char* end = internal::dtoa(d, buffer); + PutReserve(*os_, static_cast(end - buffer)); for (char* p = buffer; p != end; ++p) - os_->Put(static_cast(*p)); + PutUnsafe(*os_, static_cast(*p)); return true; } @@ -256,7 +264,12 @@ protected: #undef Z16 }; - os_->Put('\"'); + if (TargetEncoding::supportUnicode) + PutReserve(*os_, 2 + length * 6); // "\uxxxx..." + else + PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..." + + PutUnsafe(*os_, '\"'); GenericStringStream is(str); while (is.Tell() < length) { const Ch c = is.Peek(); @@ -265,13 +278,13 @@ protected: unsigned codepoint; if (!SourceEncoding::Decode(is, &codepoint)) return false; - os_->Put('\\'); - os_->Put('u'); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { - os_->Put(hexDigits[(codepoint >> 12) & 15]); - os_->Put(hexDigits[(codepoint >> 8) & 15]); - os_->Put(hexDigits[(codepoint >> 4) & 15]); - os_->Put(hexDigits[(codepoint ) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint ) & 15]); } else { RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); @@ -279,34 +292,34 @@ protected: unsigned s = codepoint - 0x010000; unsigned lead = (s >> 10) + 0xD800; unsigned trail = (s & 0x3FF) + 0xDC00; - os_->Put(hexDigits[(lead >> 12) & 15]); - os_->Put(hexDigits[(lead >> 8) & 15]); - os_->Put(hexDigits[(lead >> 4) & 15]); - os_->Put(hexDigits[(lead ) & 15]); - os_->Put('\\'); - os_->Put('u'); - os_->Put(hexDigits[(trail >> 12) & 15]); - os_->Put(hexDigits[(trail >> 8) & 15]); - os_->Put(hexDigits[(trail >> 4) & 15]); - os_->Put(hexDigits[(trail ) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(lead ) & 15]); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(trail ) & 15]); } } else if ((sizeof(Ch) == 1 || static_cast(c) < 256) && escape[static_cast(c)]) { is.Take(); - os_->Put('\\'); - os_->Put(static_cast(escape[static_cast(c)])); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, static_cast(escape[static_cast(c)])); if (escape[static_cast(c)] == 'u') { - os_->Put('0'); - os_->Put('0'); - os_->Put(hexDigits[static_cast(c) >> 4]); - os_->Put(hexDigits[static_cast(c) & 0xF]); + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, hexDigits[static_cast(c) >> 4]); + PutUnsafe(*os_, hexDigits[static_cast(c) & 0xF]); } } else - if (!Transcoder::Transcode(is, *os_)) + if (!Transcoder::TranscodeUnsafe(is, *os_)) return false; } - os_->Put('\"'); + PutUnsafe(*os_, '\"'); return true; } diff --git a/test/perftest/perftest.h b/test/perftest/perftest.h index 2b0984c..2afe641 100644 --- a/test/perftest/perftest.h +++ b/test/perftest/perftest.h @@ -65,44 +65,87 @@ public: PerfTest() : filename_(), json_(), length_(), whitespace_(), whitespace_length_() {} virtual void SetUp() { + { + const char *paths[] = { + "data/sample.json", + "bin/data/sample.json", + "../bin/data/sample.json", + "../../bin/data/sample.json", + "../../../bin/data/sample.json" + }; - const char *paths[] = { - "data/sample.json", - "bin/data/sample.json", - "../bin/data/sample.json", - "../../bin/data/sample.json", - "../../../bin/data/sample.json" - }; - FILE *fp = 0; - for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) { - fp = fopen(filename_ = paths[i], "rb"); - if (fp) - break; + FILE *fp = 0; + for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) { + fp = fopen(filename_ = paths[i], "rb"); + if (fp) + break; + } + ASSERT_TRUE(fp != 0); + + fseek(fp, 0, SEEK_END); + length_ = (size_t)ftell(fp); + fseek(fp, 0, SEEK_SET); + json_ = (char*)malloc(length_ + 1); + ASSERT_EQ(length_, fread(json_, 1, length_, fp)); + json_[length_] = '\0'; + fclose(fp); } - ASSERT_TRUE(fp != 0); - - fseek(fp, 0, SEEK_END); - length_ = (size_t)ftell(fp); - fseek(fp, 0, SEEK_SET); - json_ = (char*)malloc(length_ + 1); - ASSERT_EQ(length_, fread(json_, 1, length_, fp)); - json_[length_] = '\0'; - fclose(fp); // whitespace test - whitespace_length_ = 1024 * 1024; - whitespace_ = (char *)malloc(whitespace_length_ + 4); - char *p = whitespace_; - for (size_t i = 0; i < whitespace_length_; i += 4) { - *p++ = ' '; - *p++ = '\n'; - *p++ = '\r'; - *p++ = '\t'; + { + whitespace_length_ = 1024 * 1024; + whitespace_ = (char *)malloc(whitespace_length_ + 4); + char *p = whitespace_; + for (size_t i = 0; i < whitespace_length_; i += 4) { + *p++ = ' '; + *p++ = '\n'; + *p++ = '\r'; + *p++ = '\t'; + } + *p++ = '['; + *p++ = '0'; + *p++ = ']'; + *p++ = '\0'; + } + + // types test + { + const char *typespaths[] = { + "data/types", + "bin/types", + "../bin/types", + "../../bin/types/", + "../../../bin/types" + }; + + const char* typesfilenames[] = { + "booleans.json", + "floats.json", + "guids.json", + "integers.json", + "mixed.json", + "nulls.json", + "paragraphs.json" + }; + + for (size_t j = 0; j < sizeof(typesfilenames) / sizeof(typesfilenames[0]); j++) { + types_[j] = 0; + for (size_t i = 0; i < sizeof(typespaths) / sizeof(typespaths[0]); i++) { + char filename[256]; + sprintf(filename, "%s/%s", typespaths[i], typesfilenames[j]); + if (FILE* fp = fopen(filename, "rb")) { + fseek(fp, 0, SEEK_END); + size_t length = (size_t)ftell(fp); + fseek(fp, 0, SEEK_SET); + types_[j] = (char*)malloc(length + 1); + ASSERT_EQ(length, fread(types_[j], 1, length, fp)); + types_[j][length] = '\0'; + fclose(fp); + break; + } + } + } } - *p++ = '['; - *p++ = '0'; - *p++ = ']'; - *p++ = '\0'; } virtual void TearDown() { @@ -110,6 +153,10 @@ public: free(whitespace_); json_ = 0; whitespace_ = 0; + for (size_t i = 0; i < 7; i++) { + free(types_[i]); + types_[i] = 0; + } } private: @@ -122,6 +169,7 @@ protected: size_t length_; char *whitespace_; size_t whitespace_length_; + char *types_[7]; static const size_t kTrialCount = 1000; }; diff --git a/test/perftest/rapidjsontest.cpp b/test/perftest/rapidjsontest.cpp index 0594171..b9ac395 100644 --- a/test/perftest/rapidjsontest.cpp +++ b/test/perftest/rapidjsontest.cpp @@ -45,7 +45,10 @@ public: temp_ = (char *)malloc(length_ + 1); // Parse as a document - EXPECT_FALSE(doc_.Parse(json_).IsNull()); + EXPECT_FALSE(doc_.Parse(json_).HasParseError()); + + for (size_t i = 0; i < 7; i++) + EXPECT_FALSE(typesDoc_[i].Parse(types_[i]).HasParseError()); } virtual void TearDown() { @@ -60,6 +63,7 @@ private: protected: char *temp_; Document doc_; + Document typesDoc_[7]; }; TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler)) { @@ -250,8 +254,10 @@ TEST_F(RapidJson, DocumentAccept) { } struct NullStream { + typedef char Ch; + NullStream() /*: length_(0)*/ {} - void Put(char) { /*++length_;*/ } + void Put(Ch) { /*++length_;*/ } void Flush() {} //size_t length_; }; @@ -278,6 +284,25 @@ TEST_F(RapidJson, Writer_StringBuffer) { } } +#define TEST_TYPED(index, Name)\ +TEST_F(RapidJson, Writer_StringBuffer_##Name) {\ + for (size_t i = 0; i < kTrialCount * 10; i++) {\ + StringBuffer s(0, 1024 * 1024);\ + Writer writer(s);\ + typesDoc_[index].Accept(writer);\ + const char* str = s.GetString();\ + (void)str;\ + }\ +}\ + +TEST_TYPED(0, Booleans) +TEST_TYPED(1, Floats) +TEST_TYPED(2, Guids) +TEST_TYPED(3, Integers) +TEST_TYPED(4, Mixed) +TEST_TYPED(5, Nulls) +TEST_TYPED(6, Paragraphs) + TEST_F(RapidJson, PrettyWriter_StringBuffer) { for (size_t i = 0; i < kTrialCount; i++) { StringBuffer s(0, 2048 * 1024);