--- JSON-XS/XS.xs 2007/06/25 06:57:42 1.45 +++ JSON-XS/XS.xs 2007/06/25 22:11:39 1.46 @@ -1025,25 +1025,62 @@ else for (;;) { - SV *key, *value; - decode_ws (dec); EXPECT_CH ('"'); - key = decode_str (dec); - if (!key) - goto fail; - - decode_ws (dec); EXPECT_CH (':'); - - value = decode_sv (dec); - if (!value) - { - SvREFCNT_dec (key); - goto fail; - } - - hv_store_ent (hv, key, value, 0); - SvREFCNT_dec (key); + // heuristic: assume that + // a) decode_str + hv_store_ent are abysmally slow + // b) most hash keys are short, simple ascii text + // so try to "fast-match" such strings to avoid + // the overhead of hv_store_ent. + { + SV *value; + char *p = dec->cur; + char *e = p + 24; // only try up to 24 bytes + + for (;;) + { + if (p == e || *p < 0x20 || *p >= 0x80 || *p == '\\') + { + // slow path, back up and use decode_str + SV *key = decode_str (dec); + if (!key) + goto fail; + + decode_ws (dec); EXPECT_CH (':'); + + value = decode_sv (dec); + if (!value) + { + SvREFCNT_dec (key); + goto fail; + } + + hv_store_ent (hv, key, value, 0); + SvREFCNT_dec (key); + + break; + } + else if (*p == '"') + { + // fast path, got a simple key + char *key = dec->cur; + int len = p - key; + dec->cur = p + 1; + + decode_ws (dec); EXPECT_CH (':'); + + value = decode_sv (dec); + if (!value) + goto fail; + + hv_store (hv, key, len, value, 0); + + break; + } + + ++p; + } + } decode_ws (dec);