Skip to content

Commit 5de7258

Browse files
StilesCrisisStilesCrisis
authored andcommitted
Improve performance
Slight performance improvement over previous submission
1 parent 1a7c5ea commit 5de7258

File tree

1 file changed

+89
-83
lines changed

1 file changed

+89
-83
lines changed

include/rapidjson/reader.h

Lines changed: 89 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,8 @@ class GenericReader {
529529
\return Whether the parsing is successful.
530530
*/
531531
template <unsigned parseFlags, typename InputStream, typename Handler>
532-
ParseResult IterativeParseNext(InputStream& is, Handler& handler) {
532+
bool IterativeParseNext(InputStream& is, Handler& handler) {
533533
while (is.Peek() != '\0') {
534-
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
535534
SkipWhitespaceAndComments<parseFlags>(is);
536535

537536
Token t = Tokenize(is.Peek());
@@ -540,38 +539,52 @@ class GenericReader {
540539

541540
if (d == IterativeParsingErrorState) {
542541
HandleError(state_, is);
543-
return parseResult_;
542+
return false;
544543
}
545544

546545
state_ = d;
547546

548-
// Do not further consume streams if a root JSON has been parsed.
549-
if (state_ == IterativeParsingFinishState) {
550-
// If StopWhenDone is not set, and stray data is found post-root, flag an error.
547+
// Do not further consume streams if we've parsed a complete object or hit an error.
548+
if (IsIterativeParsingCompleteState(state_)) {
549+
// If we hit an error, we are done.
550+
if (HasParseError())
551+
return false;
552+
553+
// If StopWhenDone is not set...
551554
if (!(parseFlags & kParseStopWhenDoneFlag)) {
555+
// ... and extra non-whitespace data is found...
552556
SkipWhitespaceAndComments<parseFlags>(is);
553-
if (is.Peek() != '\0')
557+
if (is.Peek() != '\0') {
558+
// ... this is considered an error.
554559
HandleError(state_, is);
560+
return false;
561+
}
555562
}
556-
return parseResult_;
563+
564+
// We are done!
565+
return true;
557566
}
558567

568+
// If we found anything other than a delimiter, we invoked the handler, so we can return true now.
559569
if (!IsIterativeParsingDelimiterState(n))
560-
return parseResult_;
570+
return true;
561571
}
562572

563-
// Handle the end of file.
564-
if (state_ != IterativeParsingFinishState)
573+
// We reached the end of file.
574+
stack_.Clear();
575+
576+
if (state_ != IterativeParsingFinishState) {
565577
HandleError(state_, is);
578+
return false;
579+
}
566580

567-
stack_.Clear();
568-
return parseResult_;
581+
return true;
569582
}
570583

571584
//! Check if token-by-token parsing JSON text is complete
572585
/*! \return Whether the JSON has been fully decoded.
573586
*/
574-
bool IterativeParseComplete() {
587+
RAPIDJSON_FORCEINLINE bool IterativeParseComplete() {
575588
return IsIterativeParsingCompleteState(state_);
576589
}
577590

@@ -1455,30 +1468,32 @@ class GenericReader {
14551468

14561469
// States
14571470
enum IterativeParsingState {
1458-
IterativeParsingStartState = 0,
1459-
IterativeParsingFinishState,
1460-
IterativeParsingErrorState,
1471+
IterativeParsingFinishState = 0, // sink states at top
1472+
IterativeParsingErrorState, // sink states at top
1473+
IterativeParsingStartState,
14611474

14621475
// Object states
14631476
IterativeParsingObjectInitialState,
14641477
IterativeParsingMemberKeyState,
1465-
IterativeParsingKeyValueDelimiterState,
14661478
IterativeParsingMemberValueState,
1467-
IterativeParsingMemberDelimiterState,
14681479
IterativeParsingObjectFinishState,
14691480

14701481
// Array states
14711482
IterativeParsingArrayInitialState,
14721483
IterativeParsingElementState,
1473-
IterativeParsingElementDelimiterState,
14741484
IterativeParsingArrayFinishState,
14751485

14761486
// Single value state
1477-
IterativeParsingValueState
1487+
IterativeParsingValueState,
1488+
1489+
// Delimiter states (at bottom)
1490+
IterativeParsingElementDelimiterState,
1491+
IterativeParsingMemberDelimiterState,
1492+
IterativeParsingKeyValueDelimiterState,
1493+
1494+
cIterativeParsingStateCount
14781495
};
14791496

1480-
enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };
1481-
14821497
// Tokens
14831498
enum Token {
14841499
LeftBracketToken = 0,
@@ -1529,6 +1544,18 @@ class GenericReader {
15291544
RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
15301545
// current state x one lookahead token -> new state
15311546
static const char G[cIterativeParsingStateCount][kTokenCount] = {
1547+
// Finish(sink state)
1548+
{
1549+
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1550+
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1551+
IterativeParsingErrorState
1552+
},
1553+
// Error(sink state)
1554+
{
1555+
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1556+
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1557+
IterativeParsingErrorState
1558+
},
15321559
// Start
15331560
{
15341561
IterativeParsingArrayInitialState, // Left bracket
@@ -1543,18 +1570,6 @@ class GenericReader {
15431570
IterativeParsingValueState, // Null
15441571
IterativeParsingValueState // Number
15451572
},
1546-
// Finish(sink state)
1547-
{
1548-
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1549-
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1550-
IterativeParsingErrorState
1551-
},
1552-
// Error(sink state)
1553-
{
1554-
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1555-
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1556-
IterativeParsingErrorState
1557-
},
15581573
// ObjectInitial
15591574
{
15601575
IterativeParsingErrorState, // Left bracket
@@ -1583,20 +1598,6 @@ class GenericReader {
15831598
IterativeParsingErrorState, // Null
15841599
IterativeParsingErrorState // Number
15851600
},
1586-
// KeyValueDelimiter
1587-
{
1588-
IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1589-
IterativeParsingErrorState, // Right bracket
1590-
IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1591-
IterativeParsingErrorState, // Right curly bracket
1592-
IterativeParsingErrorState, // Comma
1593-
IterativeParsingErrorState, // Colon
1594-
IterativeParsingMemberValueState, // String
1595-
IterativeParsingMemberValueState, // False
1596-
IterativeParsingMemberValueState, // True
1597-
IterativeParsingMemberValueState, // Null
1598-
IterativeParsingMemberValueState // Number
1599-
},
16001601
// MemberValue
16011602
{
16021603
IterativeParsingErrorState, // Left bracket
@@ -1611,20 +1612,6 @@ class GenericReader {
16111612
IterativeParsingErrorState, // Null
16121613
IterativeParsingErrorState // Number
16131614
},
1614-
// MemberDelimiter
1615-
{
1616-
IterativeParsingErrorState, // Left bracket
1617-
IterativeParsingErrorState, // Right bracket
1618-
IterativeParsingErrorState, // Left curly bracket
1619-
IterativeParsingObjectFinishState, // Right curly bracket
1620-
IterativeParsingErrorState, // Comma
1621-
IterativeParsingErrorState, // Colon
1622-
IterativeParsingMemberKeyState, // String
1623-
IterativeParsingErrorState, // False
1624-
IterativeParsingErrorState, // True
1625-
IterativeParsingErrorState, // Null
1626-
IterativeParsingErrorState // Number
1627-
},
16281615
// ObjectFinish(sink state)
16291616
{
16301617
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
@@ -1659,6 +1646,18 @@ class GenericReader {
16591646
IterativeParsingErrorState, // Null
16601647
IterativeParsingErrorState // Number
16611648
},
1649+
// ArrayFinish(sink state)
1650+
{
1651+
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1652+
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1653+
IterativeParsingErrorState
1654+
},
1655+
// Single Value (sink state)
1656+
{
1657+
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1658+
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1659+
IterativeParsingErrorState
1660+
},
16621661
// ElementDelimiter
16631662
{
16641663
IterativeParsingArrayInitialState, // Left bracket(push Element state)
@@ -1673,18 +1672,34 @@ class GenericReader {
16731672
IterativeParsingElementState, // Null
16741673
IterativeParsingElementState // Number
16751674
},
1676-
// ArrayFinish(sink state)
1675+
// MemberDelimiter
16771676
{
1678-
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1679-
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1680-
IterativeParsingErrorState
1677+
IterativeParsingErrorState, // Left bracket
1678+
IterativeParsingErrorState, // Right bracket
1679+
IterativeParsingErrorState, // Left curly bracket
1680+
IterativeParsingObjectFinishState, // Right curly bracket
1681+
IterativeParsingErrorState, // Comma
1682+
IterativeParsingErrorState, // Colon
1683+
IterativeParsingMemberKeyState, // String
1684+
IterativeParsingErrorState, // False
1685+
IterativeParsingErrorState, // True
1686+
IterativeParsingErrorState, // Null
1687+
IterativeParsingErrorState // Number
16811688
},
1682-
// Single Value (sink state)
1689+
// KeyValueDelimiter
16831690
{
1684-
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1685-
IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1686-
IterativeParsingErrorState
1687-
}
1691+
IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1692+
IterativeParsingErrorState, // Right bracket
1693+
IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1694+
IterativeParsingErrorState, // Right curly bracket
1695+
IterativeParsingErrorState, // Comma
1696+
IterativeParsingErrorState, // Colon
1697+
IterativeParsingMemberValueState, // String
1698+
IterativeParsingMemberValueState, // False
1699+
IterativeParsingMemberValueState, // True
1700+
IterativeParsingMemberValueState, // Null
1701+
IterativeParsingMemberValueState // Number
1702+
},
16881703
}; // End of G
16891704

16901705
return static_cast<IterativeParsingState>(G[state][token]);
@@ -1866,20 +1881,11 @@ class GenericReader {
18661881
}
18671882

18681883
RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) {
1869-
const unsigned int delimiterStateMask =
1870-
(1 << IterativeParsingKeyValueDelimiterState) |
1871-
(1 << IterativeParsingMemberDelimiterState) |
1872-
(1 << IterativeParsingElementDelimiterState);
1873-
1874-
return !!((1 << s) & delimiterStateMask);
1884+
return s >= IterativeParsingElementDelimiterState;
18751885
}
18761886

18771887
RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) {
1878-
const unsigned int completeStateMask =
1879-
(1 << IterativeParsingFinishState) |
1880-
(1 << IterativeParsingErrorState);
1881-
1882-
return !!((1 << s) & completeStateMask);
1888+
return s <= IterativeParsingErrorState;
18831889
}
18841890

18851891
template <unsigned parseFlags, typename InputStream, typename Handler>

0 commit comments

Comments
 (0)