shithub: hugo

Download patch

ref: 243694102a60da2fb1050020f68384539f9f9ef5
parent: 31535261610b34131c68ec760db8b29cac1548dd
author: Bjørn Erik Pedersen <[email protected]>
date: Thu Dec 7 16:46:46 EST 2017

Remove the goroutines from the shortcode lexer

It was clever, but storing the items in a slice is faster -- and it gives room to more goroutines in other places.

```bash
benchmark                     old ns/op     new ns/op     delta
BenchmarkShortcodeLexer-4     180173        79614         -55.81%

benchmark                     old allocs     new allocs     delta
BenchmarkShortcodeLexer-4     309            328            +6.15%

benchmark                     old bytes     new bytes     delta
BenchmarkShortcodeLexer-4     35456         47008         +32.58%
```

--- a/hugolib/shortcodeparser.go
+++ b/hugolib/shortcodeparser.go
@@ -159,7 +159,7 @@
 	openShortcodes     map[string]bool // set of shortcodes in open state
 
 	// items delivered to client
-	items chan item
+	items []item
 }
 
 // note: the input position here is normally 0 (start), but
@@ -172,9 +172,9 @@
 		currRightDelimItem: tRightDelimScNoMarkup,
 		pos:                inputPosition,
 		openShortcodes:     make(map[string]bool),
-		items:              make(chan item),
+		items:              make([]item, 0, 5),
 	}
-	go lexer.runShortcodeLexer()
+	lexer.runShortcodeLexer()
 	return lexer
 }
 
@@ -184,8 +184,6 @@
 	for l.state = lexTextOutsideShortcodes; l.state != nil; {
 		l.state = l.state(l)
 	}
-
-	close(l.items)
 }
 
 // state functions
@@ -227,7 +225,7 @@
 
 // sends an item back to the client.
 func (l *pagelexer) emit(t itemType) {
-	l.items <- item{t, l.start, l.input[l.start:l.pos]}
+	l.items = append(l.items, item{t, l.start, l.input[l.start:l.pos]})
 	l.start = l.pos
 }
 
@@ -239,7 +237,7 @@
 		}
 		return r
 	}, l.input[l.start:l.pos])
-	l.items <- item{t, l.start, val}
+	l.items = append(l.items, item{t, l.start, val})
 	l.start = l.pos
 }
 
@@ -260,13 +258,14 @@
 
 // nil terminates the parser
 func (l *pagelexer) errorf(format string, args ...interface{}) stateFunc {
-	l.items <- item{tError, l.start, fmt.Sprintf(format, args...)}
+	l.items = append(l.items, item{tError, l.start, fmt.Sprintf(format, args...)})
 	return nil
 }
 
 // consumes and returns the next item
 func (l *pagelexer) nextItem() item {
-	item := <-l.items
+	item := l.items[0]
+	l.items = l.items[1:]
 	l.lastPos = item.pos
 	return item
 }