Skip to content

Commit 37494d3

Browse files
committed
Switch json parsing to read_chars for performance
Avoids the overhead of read_char for every character. Benchmark reading example.json 10 times from https://code.google.com/p/rapidjson/wiki/Performance Before: 2.55s After: 0.16s Regression testing is already done by isrustfastyet.
1 parent 58eb70a commit 37494d3

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

src/libextra/json.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -481,22 +481,30 @@ pub fn to_pretty_str(json: &Json) -> ~str {
481481
io::with_str_writer(|wr| to_pretty_writer(wr, json))
482482
}
483483

484+
static BUF_SIZE : uint = 64000;
485+
484486
#[allow(missing_doc)]
485487
pub struct Parser {
486488
priv rdr: @io::Reader,
489+
priv buf: ~[char],
490+
priv buf_idx: uint,
487491
priv ch: char,
488492
priv line: uint,
489493
priv col: uint,
490494
}
491495

492496
/// Decode a json value from an io::reader
493497
pub fn Parser(rdr: @io::Reader) -> Parser {
494-
Parser {
498+
let mut p = Parser {
495499
rdr: rdr,
496-
ch: rdr.read_char(),
500+
buf: rdr.read_chars(BUF_SIZE),
501+
buf_idx: 0,
502+
ch: 0 as char,
497503
line: 1,
498-
col: 1,
499-
}
504+
col: 0,
505+
};
506+
p.bump();
507+
p
500508
}
501509

502510
impl Parser {
@@ -521,13 +529,26 @@ impl Parser {
521529
fn eof(&self) -> bool { self.ch == -1 as char }
522530

523531
fn bump(&mut self) {
524-
self.ch = self.rdr.read_char();
532+
if self.eof() {
533+
return;
534+
}
535+
536+
self.col += 1u;
537+
538+
if self.buf_idx >= self.buf.len() {
539+
self.buf = self.rdr.read_chars(BUF_SIZE);
540+
if self.buf.len() == 0 {
541+
self.ch = -1 as char;
542+
return;
543+
}
544+
self.buf_idx = 0;
545+
}
546+
self.ch = self.buf[self.buf_idx];
547+
self.buf_idx += 1;
525548

526549
if self.ch == '\n' {
527550
self.line += 1u;
528551
self.col = 1u;
529-
} else {
530-
self.col += 1u;
531552
}
532553
}
533554

0 commit comments

Comments
 (0)