optimize cuuAndEd write
Vladimir Bauer
5 years ago
|
0 |
package cwriter
|
|
1 |
|
|
2 |
import (
|
|
3 |
"bytes"
|
|
4 |
"fmt"
|
|
5 |
"io/ioutil"
|
|
6 |
"strconv"
|
|
7 |
"testing"
|
|
8 |
)
|
|
9 |
|
|
10 |
func BenchmarkWithFprintf(b *testing.B) {
|
|
11 |
cuuAndEd := "\x1b[%dA\x1b[J"
|
|
12 |
for i := 0; i < b.N; i++ {
|
|
13 |
fmt.Fprintf(ioutil.Discard, cuuAndEd, 4)
|
|
14 |
}
|
|
15 |
}
|
|
16 |
|
|
17 |
func BenchmarkWithJoin(b *testing.B) {
|
|
18 |
bCuuAndEd := [][]byte{[]byte("\x1b["), []byte("A\x1b[J")}
|
|
19 |
for i := 0; i < b.N; i++ {
|
|
20 |
ioutil.Discard.Write(bytes.Join(bCuuAndEd, []byte(strconv.Itoa(4))))
|
|
21 |
}
|
|
22 |
}
|
|
23 |
|
|
24 |
func BenchmarkWithAppend(b *testing.B) {
|
|
25 |
escOpen := []byte("\x1b[")
|
|
26 |
cuuAndEd := []byte("A\x1b[J")
|
|
27 |
for i := 0; i < b.N; i++ {
|
|
28 |
ioutil.Discard.Write(append(strconv.AppendInt(escOpen, 4, 10), cuuAndEd...))
|
|
29 |
}
|
|
30 |
}
|
|
31 |
|
|
32 |
func BenchmarkWithCopy(b *testing.B) {
|
|
33 |
w := New(ioutil.Discard)
|
|
34 |
w.lineCount = 4
|
|
35 |
for i := 0; i < b.N; i++ {
|
|
36 |
w.ansiCuuAndEd()
|
|
37 |
}
|
|
38 |
}
|
| 4 | 4 |
"errors"
|
| 5 | 5 |
"io"
|
| 6 | 6 |
"os"
|
|
7 |
"strconv"
|
| 7 | 8 |
|
| 8 | 9 |
"github.com/mattn/go-isatty"
|
| 9 | 10 |
)
|
|
| 11 | 12 |
// NotATTY not a TeleTYpewriter error.
|
| 12 | 13 |
var NotATTY = errors.New("not a terminal")
|
| 13 | 14 |
|
| 14 | |
const cuuAndEd = "\x1b[%dA\x1b[J"
|
|
15 |
// http://ascii-table.com/ansi-escape-sequences.php
|
|
16 |
const (
|
|
17 |
escOpen = "\x1b["
|
|
18 |
cuuAndEd = "A\x1b[J"
|
|
19 |
)
|
| 15 | 20 |
|
| 16 | 21 |
// Writer is a buffered the writer that updates the terminal. The
|
| 17 | 22 |
// contents of writer will be flushed when Flush is called.
|
|
| 68 | 73 |
tw, _, err := GetSize(w.fd)
|
| 69 | 74 |
return tw, err
|
| 70 | 75 |
}
|
|
76 |
|
|
77 |
func (w *Writer) ansiCuuAndEd() {
|
|
78 |
buf := make([]byte, 8)
|
|
79 |
buf = strconv.AppendInt(buf[:copy(buf, escOpen)], int64(w.lineCount), 10)
|
|
80 |
w.out.Write(append(buf, cuuAndEd...))
|
|
81 |
}
|
| 2 | 2 |
package cwriter
|
| 3 | 3 |
|
| 4 | 4 |
import (
|
| 5 | |
"fmt"
|
| 6 | |
|
| 7 | 5 |
"golang.org/x/sys/unix"
|
| 8 | 6 |
)
|
| 9 | 7 |
|
| 10 | 8 |
func (w *Writer) clearLines() {
|
| 11 | |
fmt.Fprintf(w.out, cuuAndEd, w.lineCount)
|
|
9 |
w.ansiCuuAndEd()
|
| 12 | 10 |
}
|
| 13 | 11 |
|
| 14 | 12 |
// GetSize returns the dimensions of the given terminal.
|
| 2 | 2 |
package cwriter
|
| 3 | 3 |
|
| 4 | 4 |
import (
|
| 5 | |
"fmt"
|
| 6 | 5 |
"syscall"
|
| 7 | 6 |
"unsafe"
|
|
7 |
|
|
8 |
"github.com/mattn/go-isatty"
|
| 8 | 9 |
)
|
| 9 | 10 |
|
| 10 | 11 |
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
| 36 | 37 |
}
|
| 37 | 38 |
|
| 38 | 39 |
func (w *Writer) clearLines() {
|
| 39 | |
if !w.isTerminal {
|
| 40 | |
fmt.Fprintf(w.out, cuuAndEd, w.lineCount)
|
|
40 |
if !w.isTerminal && isatty.IsCygwinTerminal(w.fd) {
|
|
41 |
w.ansiCuuAndEd()
|
| 41 | 42 |
}
|
| 42 | 43 |
|
| 43 | 44 |
info := new(consoleScreenBufferInfo)
|