about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-08 14:34:54 -0700
committerbors <bors@rust-lang.org>2013-07-08 14:34:54 -0700
commitf503e539bf60416a731f9ecc12b6aab31ef2fe87 (patch)
treec1ff5d04cfd8079d5e500c96ac69305ff56b1411
parentf7b293bc75684a368e20567b5987c482dc5f8550 (diff)
parent149c976aa0b6441b93f2e2140e10e0424d39ea17 (diff)
downloadrust-f503e539bf60416a731f9ecc12b6aab31ef2fe87.tar.gz
rust-f503e539bf60416a731f9ecc12b6aab31ef2fe87.zip
auto merge of #7608 : glinscott/rust/json_perf, r=pcwalton
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.
-rw-r--r--src/libextra/json.rs35
-rw-r--r--src/libstd/char.rs3
2 files changed, 30 insertions, 8 deletions
diff --git a/src/libextra/json.rs b/src/libextra/json.rs
index b9b2099d7c2..67ffd53a0e8 100644
--- a/src/libextra/json.rs
+++ b/src/libextra/json.rs
@@ -481,9 +481,13 @@ pub fn to_pretty_str(json: &Json) -> ~str {
     io::with_str_writer(|wr| to_pretty_writer(wr, json))
 }
 
+static BUF_SIZE : uint = 64000;
+
 #[allow(missing_doc)]
 pub struct Parser {
     priv rdr: @io::Reader,
+    priv buf: ~[char],
+    priv buf_idx: uint,
     priv ch: char,
     priv line: uint,
     priv col: uint,
@@ -491,12 +495,16 @@ pub struct Parser {
 
 /// Decode a json value from an io::reader
 pub fn Parser(rdr: @io::Reader) -> Parser {
-    Parser {
+    let mut p = Parser {
         rdr: rdr,
-        ch: rdr.read_char(),
+        buf: rdr.read_chars(BUF_SIZE),
+        buf_idx: 0,
+        ch: 0 as char,
         line: 1,
-        col: 1,
-    }
+        col: 0,
+    };
+    p.bump();
+    p
 }
 
 impl Parser {
@@ -521,13 +529,26 @@ impl Parser {
     fn eof(&self) -> bool { self.ch == -1 as char }
 
     fn bump(&mut self) {
-        self.ch = self.rdr.read_char();
+        if self.eof() {
+            return;
+        }
+
+        self.col += 1u;
+
+        if self.buf_idx >= self.buf.len() {
+            self.buf = self.rdr.read_chars(BUF_SIZE);
+            if self.buf.len() == 0 {
+                self.ch = -1 as char;
+                return;
+            }
+            self.buf_idx = 0;
+        }
+        self.ch = self.buf[self.buf_idx];
+        self.buf_idx += 1;
 
         if self.ch == '\n' {
             self.line += 1u;
             self.col = 1u;
-        } else {
-            self.col += 1u;
         }
     }
 
diff --git a/src/libstd/char.rs b/src/libstd/char.rs
index 6a9555f4efc..47473c2faba 100644
--- a/src/libstd/char.rs
+++ b/src/libstd/char.rs
@@ -82,7 +82,8 @@ pub fn is_uppercase(c: char) -> bool { general_category::Lu(c) }
 ///
 #[inline]
 pub fn is_whitespace(c: char) -> bool {
-    ('\x09' <= c && c <= '\x0d')
+    c == ' '
+        || ('\x09' <= c && c <= '\x0d')
         || general_category::Zs(c)
         || general_category::Zl(c)
         || general_category::Zp(c)