scanner: speed up Scanner.skip_whitespace (~2-3% speed up of `-o x.c cmd/v`)

pull/9987/head
Delyan Angelov 2021-05-03 14:14:32 +03:00
parent d3f2d6f6df
commit 597a774d36
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
4 changed files with 29 additions and 39 deletions

View File

@ -952,7 +952,7 @@ pub fn (s string) ends_with(p string) bool {
return false return false
} }
for i in 0 .. p.len { for i in 0 .. p.len {
if p[i] != s[s.len - p.len + i] { if unsafe { p.str[i] != s.str[s.len - p.len + i] } {
return false return false
} }
} }
@ -1087,12 +1087,13 @@ pub fn (s string) find_between(start string, end string) string {
} }
// is_space returns `true` if the byte is a white space character. // is_space returns `true` if the byte is a white space character.
// The following list is considered white space characters: ` `, `\n`, `\t`, `\v`, `\f`, `\r`, 0x85, 0xa0 // The following list is considered white space characters: ` `, `\t`, `\n`, `\v`, `\f`, `\r`, 0x85, 0xa0
// Example: assert byte(` `).is_space() == true // Example: assert byte(` `).is_space() == true
[inline]
pub fn (c byte) is_space() bool { pub fn (c byte) is_space() bool {
// 0x0085 is NEXT LINE (NEL) // 0x85 is NEXT LINE (NEL)
// 0x00a0 is NO-BREAK SPACE // 0xa0 is NO-BREAK SPACE
return c in [` `, `\n`, `\t`, `\v`, `\f`, `\r`, 0x85, 0xa0] return c == 32 || (c > 8 && c < 14) || (c == 0x85) || (c == 0xa0)
} }
// trim_space strips any of ` `, `\n`, `\t`, `\v`, `\f`, `\r` from the start and end of the string. // trim_space strips any of ` `, `\n`, `\t`, `\v`, `\f`, `\r` from the start and end of the string.

View File

@ -5,27 +5,15 @@ module mathutil
[inline] [inline]
pub fn min<T>(a T, b T) T { pub fn min<T>(a T, b T) T {
if a < b { return if a < b { a } else { b }
return a
} else {
return b
}
} }
[inline] [inline]
pub fn max<T>(a T, b T) T { pub fn max<T>(a T, b T) T {
if a > b { return if a > b { a } else { b }
return a
} else {
return b
}
} }
[inline] [inline]
pub fn abs<T>(a T) T { pub fn abs<T>(a T) T {
if a > 0 { return if a > 0 { a } else { -a }
return a
} else {
return -a
}
} }

View File

@ -17,6 +17,8 @@ const (
double_quote = `"` double_quote = `"`
// char used as number separator // char used as number separator
num_sep = `_` num_sep = `_`
b_lf = 10
b_cr = 13
) )
pub struct Scanner { pub struct Scanner {
@ -492,18 +494,22 @@ fn (mut s Scanner) ident_number() string {
} }
} }
[inline] [direct_array_access; inline]
fn (mut s Scanner) skip_whitespace() { fn (mut s Scanner) skip_whitespace() {
// if s.is_vh { println('vh') return } for s.pos < s.text.len {
for s.pos < s.text.len && s.text[s.pos].is_space() { c := s.text[s.pos]
if util.is_nl(s.text[s.pos]) && s.is_vh { if !c.is_space() {
return return
} }
if s.pos + 1 < s.text.len && s.text[s.pos] == `\r` && s.text[s.pos + 1] == `\n` { c_is_nl := c == scanner.b_cr || c == scanner.b_lf
if c_is_nl && s.is_vh {
return
}
if s.pos + 1 < s.text.len && c == scanner.b_cr && s.text[s.pos + 1] == scanner.b_lf {
s.is_crlf = true s.is_crlf = true
} }
// Count \r\n as one line // Count \r\n as one line
if util.is_nl(s.text[s.pos]) && !s.expect('\r\n', s.pos - 1) { if c_is_nl && !(s.pos > 0 && s.text[s.pos - 1] == scanner.b_cr && c == scanner.b_lf) {
s.inc_line_number() s.inc_line_number()
} }
s.pos++ s.pos++
@ -975,7 +981,7 @@ fn (mut s Scanner) text_scan() token.Token {
start := s.pos + 1 start := s.pos + 1
s.ignore_line() s.ignore_line()
mut comment_line_end := s.pos mut comment_line_end := s.pos
if s.text[s.pos - 1] == `\r` { if s.text[s.pos - 1] == scanner.b_cr {
comment_line_end-- comment_line_end--
} else { } else {
// fix line_nr, \n was read; the comment is marked on the next line // fix line_nr, \n was read; the comment is marked on the next line
@ -987,7 +993,7 @@ fn (mut s Scanner) text_scan() token.Token {
mut comment := s.line_comment mut comment := s.line_comment
// Find out if this comment is on its own line (for vfmt) // Find out if this comment is on its own line (for vfmt)
mut is_separate_line_comment := true mut is_separate_line_comment := true
for j := start - 2; j >= 0 && s.text[j] != `\n`; j-- { for j := start - 2; j >= 0 && s.text[j] != scanner.b_lf; j-- {
if s.text[j] !in [`\t`, ` `] { if s.text[j] !in [`\t`, ` `] {
is_separate_line_comment = false is_separate_line_comment = false
} }
@ -1015,7 +1021,7 @@ fn (mut s Scanner) text_scan() token.Token {
s.line_nr-- s.line_nr--
s.error('comment not terminated') s.error('comment not terminated')
} }
if s.text[s.pos] == `\n` { if s.text[s.pos] == scanner.b_lf {
s.inc_line_number() s.inc_line_number()
continue continue
} }
@ -1098,7 +1104,7 @@ fn (mut s Scanner) ident_string() string {
if start_char == s.quote if start_char == s.quote
|| (start_char == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter)) { || (start_char == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter)) {
start++ start++
} else if start_char == `\n` { } else if start_char == scanner.b_lf {
s.inc_line_number() s.inc_line_number()
} }
s.is_inside_string = false s.is_inside_string = false
@ -1120,10 +1126,10 @@ fn (mut s Scanner) ident_string() string {
if c == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter) { if c == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter) {
break break
} }
if c == `\r` { if c == scanner.b_cr {
n_cr_chars++ n_cr_chars++
} }
if c == `\n` { if c == scanner.b_lf {
s.inc_line_number() s.inc_line_number()
} }
// Don't allow \0 // Don't allow \0
@ -1288,9 +1294,9 @@ fn (mut s Scanner) ignore_line() {
s.inc_line_number() s.inc_line_number()
} }
[inline] [direct_array_access; inline]
fn (mut s Scanner) eat_to_end_of_line() { fn (mut s Scanner) eat_to_end_of_line() {
for s.pos < s.text.len && s.text[s.pos] != `\n` { for s.pos < s.text.len && s.text[s.pos] != scanner.b_lf {
s.pos++ s.pos++
} }
} }

View File

@ -10,11 +10,6 @@ pub fn is_func_char(c byte) bool {
return (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`) || c == `_` || c.is_digit() return (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`) || c == `_` || c.is_digit()
} }
[inline]
pub fn is_nl(c byte) bool {
return c == `\r` || c == `\n`
}
pub fn contains_capital(s string) bool { pub fn contains_capital(s string) bool {
for c in s { for c in s {
if c >= `A` && c <= `Z` { if c >= `A` && c <= `Z` {