Skip to content

Commit

Permalink
BTreeSet is really slow; don't use it
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuki Izumi authored and Yuki Izumi committed Apr 15, 2017
1 parent bf576b3 commit 0c9d8af
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 50 deletions.
29 changes: 7 additions & 22 deletions src/html.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std;
use std::io::Write;
use std::iter::FromIterator;
use std::collections::BTreeMap;

use nodes::{TableAlignment, NodeValue, ListType, AstNode};
use parser::ComrakOptions;
Expand Down Expand Up @@ -97,27 +95,14 @@ impl<'o> HtmlFormatter<'o> {
}

fn escape(&mut self, buffer: &str) {
lazy_static! {
static ref ESCAPE_TABLE: BTreeMap<u8, &'static str> = BTreeMap::from_iter(
vec![(b'"', "&quot;"),
(b'&', "&amp;"),
// Secure mode only:
// ('\'', "&#39;"),
// ('/', "&#47;"),
(b'<', "&lt;"),
(b'>', "&gt;"),
]);
}

for c in buffer.as_bytes() {
match ESCAPE_TABLE.get(c) {
Some(s) => {
self.write_all(s.as_bytes()).unwrap();
}
None => {
self.write_all(&[*c]).unwrap();
}
};
match *c {
b'"' => self.write_all(b"&quot;").unwrap(),
b'&' => self.write_all(b"&amp;").unwrap(),
b'<' => self.write_all(b"&lt;").unwrap(),
b'>' => self.write_all(b"&gt;").unwrap(),
_ => self.v.push(*c),
}
}
}

Expand Down
36 changes: 24 additions & 12 deletions src/parser/autolink.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use unicode_categories::UnicodeCategories;
use std::iter::FromIterator;
use std::collections::BTreeSet;
use typed_arena::Arena;
use nodes::{NodeValue, NodeLink, AstNode};
use ctype::{isspace, isalpha, isalnum};
Expand Down Expand Up @@ -59,12 +57,17 @@ fn www_match<'a>(arena: &'a Arena<AstNode<'a>>,
i: usize)
-> Option<(&'a AstNode<'a>, usize, usize)> {
lazy_static! {
static ref WWW_DELIMS: BTreeSet<u8> = BTreeSet::from_iter(
vec![b'*', b'_', b'~', b'(', b'[']);
static ref WWW_DELIMS: [bool; 256] = {
let mut sc = [false; 256];
for c in &[b'*', b'_', b'~', b'(', b'['] {
sc[*c as usize] = true;
}
sc
};
}

if i > 0 && !isspace(&contents.as_bytes()[i - 1]) &&
!WWW_DELIMS.contains(&contents.as_bytes()[i - 1]) {
!WWW_DELIMS[contents.as_bytes()[i - 1] as usize] {
return None;
}

Expand Down Expand Up @@ -130,9 +133,13 @@ fn is_valid_hostchar(ch: char) -> bool {

fn autolink_delim(data: &str, mut link_end: usize) -> usize {
lazy_static! {
static ref LINK_END_ASSORTMENT: BTreeSet<u8> = BTreeSet::from_iter(
vec![b'?', b'!', b'.', b',', b':', b'*',
b'_', b'~', b'\'', b'"']);
static ref LINK_END_ASSORTMENT: [bool; 256] = {
let mut sc = [false; 256];
for c in &[b'?', b'!', b'.', b',', b':', b'*', b'_', b'~', b'\'', b'"'] {
sc[*c as usize] = true;
}
sc
};
}

for i in 0..link_end {
Expand All @@ -151,7 +158,7 @@ fn autolink_delim(data: &str, mut link_end: usize) -> usize {
None
};

if LINK_END_ASSORTMENT.contains(&cclose) {
if LINK_END_ASSORTMENT[cclose as usize] {
link_end -= 1;
} else if cclose == b';' {
let mut new_end = link_end - 2;
Expand Down Expand Up @@ -242,8 +249,13 @@ fn email_match<'a>(arena: &'a Arena<AstNode<'a>>,
i: usize)
-> Option<(&'a AstNode<'a>, usize, usize)> {
lazy_static! {
static ref EMAIL_OK_SET: BTreeSet<u8> = BTreeSet::from_iter(
vec![b'.', b'+', b'-', b'_']);
static ref EMAIL_OK_SET: [bool; 256] = {
let mut sc = [false; 256];
for c in &[b'.', b'+', b'-', b'_'] {
sc[*c as usize] = true;
}
sc
};
}

let size = contents.len();
Expand All @@ -254,7 +266,7 @@ fn email_match<'a>(arena: &'a Arena<AstNode<'a>>,
while rewind < i {
let c = contents.as_bytes()[i - rewind - 1];

if isalnum(&c) || EMAIL_OK_SET.contains(&c) {
if isalnum(&c) || EMAIL_OK_SET[c as usize] {
rewind += 1;
continue;
}
Expand Down
25 changes: 9 additions & 16 deletions src/parser/inlines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use scanners;
use ctype::{isspace, ispunct};
use entity;
use strings;
use std::collections::{BTreeSet, HashMap};
use std::collections::HashMap;

pub struct Subject<'a, 'r, 'o> {
pub arena: &'a Arena<AstNode<'a>>,
Expand Down Expand Up @@ -267,24 +267,17 @@ impl<'a, 'r, 'o> Subject<'a, 'r, 'o> {

pub fn find_special_char(&self) -> usize {
lazy_static! {
static ref SPECIAL_CHARS: BTreeSet<u8> =
[b'\n',
b'\r',
b'_',
b'*',
b'"',
b'`',
b'\\',
b'&',
b'<',
b'[',
b']',
b'!',
].iter().cloned().collect();
static ref SPECIAL_CHARS: [bool; 256] = {
let mut sc = [false; 256];
for c in &[b'\n', b'\r', b'_', b'*', b'"', b'`', b'\\', b'&', b'<', b'[', b']', b'!'] {
sc[*c as usize] = true;
}
sc
};
}

for n in self.pos..self.input.len() {
if SPECIAL_CHARS.contains(&self.input.as_bytes()[n]) {
if SPECIAL_CHARS[self.input.as_bytes()[n] as usize] {
return n;
}
if self.options.ext_strikethrough && self.input.as_bytes()[n] == b'~' {
Expand Down

0 comments on commit 0c9d8af

Please sign in to comment.