Commit 3a528165 authored by Kirill Smelkov's avatar Kirill Smelkov

x pyquote: 5x speedup by avoiding calling QuoteRune for IsPrint characters

parent f9046fbe
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
package main package main
import ( import (
"bytes"
"strconv" "strconv"
"strings"
"unicode/utf8" "unicode/utf8"
"lab.nexedi.com/kirr/go123/mem" "lab.nexedi.com/kirr/go123/mem"
...@@ -20,23 +20,24 @@ func pyQuote(s string) string { ...@@ -20,23 +20,24 @@ func pyQuote(s string) string {
const hex = "0123456789abcdef" const hex = "0123456789abcdef"
func pyQuoteBytes(b []byte) []byte { func pyQuoteBytes(b []byte) []byte {
s := mem.String(b) buf := make([]byte, 0, len(b) + 2/*quotes*/) // XXX revisit and do *1.5 ? or *2
buf := make([]byte, 0, len(s) + 2/*quotes*/)
// smartquotes: choose ' or " as quoting character // smartquotes: choose ' or " as quoting character
// https://github.com/python/cpython/blob/v2.7.13-116-g1aa1803b3d/Objects/stringobject.c#L947 // https://github.com/python/cpython/blob/v2.7.13-116-g1aa1803b3d/Objects/stringobject.c#L947
quote := byte('\'') quote := byte('\'')
noquote := byte('"') noquote := byte('"')
if strings.ContainsRune(s, '\'') && !strings.ContainsRune(s, '"') { if bytes.ContainsRune(b, '\'') && !bytes.ContainsRune(b, '"') {
quote, noquote = noquote, quote quote, noquote = noquote, quote
} }
buf = append(buf, quote) buf = append(buf, quote)
for i, r := range s { for len(b) > 0 {
r, size := utf8.DecodeRune(b)
switch r { switch r {
case utf8.RuneError: case utf8.RuneError:
buf = append(buf, '\\', 'x', hex[s[i]>>4], hex[s[i]&0xf]) buf = append(buf, '\\', 'x', hex[b[0]>>4], hex[b[0]&0xf])
case '\\', rune(quote): case '\\', rune(quote):
buf = append(buf, '\\', byte(r)) buf = append(buf, '\\', byte(r))
case rune(noquote): case rune(noquote):
...@@ -55,7 +56,11 @@ func pyQuoteBytes(b []byte) []byte { ...@@ -55,7 +56,11 @@ func pyQuoteBytes(b []byte) []byte {
switch { switch {
case r < ' ': case r < ' ':
// we already converted to \<letter> what python represents as such above // we already converted to \<letter> what python represents as such above
buf = append(buf, '\\', 'x', hex[s[i]>>4], hex[s[i]&0xf]) buf = append(buf, '\\', 'x', hex[b[0]>>4], hex[b[0]&0xf])
case strconv.IsPrint(r):
// shortcut to avoid calling QuoteRune
buf = append(buf, b[:size]...)
default: default:
// we already handled ', " and (< ' ') above, so now it // we already handled ', " and (< ' ') above, so now it
...@@ -65,6 +70,8 @@ func pyQuoteBytes(b []byte) []byte { ...@@ -65,6 +70,8 @@ func pyQuoteBytes(b []byte) []byte {
buf = append(buf, rq...) buf = append(buf, rq...)
} }
} }
b = b[size:]
} }
buf = append(buf, quote) buf = append(buf, quote)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment