diff --git a/README.md b/README.md index b1de2b9..cf55aaf 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ To start replaying: `BeamNGMockOg replay [--loop] -a 127.0.0.1 -p 4443 -i sunburstManual.bin` - `loop` allows the replay functionality to keep replaying the same data file + To start recording: `BeamNGMockOg record -a 127.0.0.1 -p 4443 -o sunburstDCT.bin` @@ -22,6 +23,7 @@ To start recording: Use `tcpdump` to listen to the socket and check if data is coming through: `tcpdump -i any udp port -X` + ### Benchmark Run with: `go test ./mockserver -bench=BenchmarkReplayAsync -benchmem -benchtime=1x -memprofile=mem.pprof` @@ -33,16 +35,10 @@ Analyze the output with: or `go tool pprof -http=:8080 mem.pprof` -#### Previous results: -goos: linux -goarch: amd64 -pkg: github.com/ESilva15/BeamNGMockOg/mockserver -cpu: AMD Ryzen 5 5600G with Radeon Graphics -BenchmarkReplayAsync-12 1 109433574741 ns/op 4533008 B/op 66059 allocs/op -PASS -ok github.com/ESilva15/BeamNGMockOg/mockserver 109.438s -#### Current results +#### Previous results: +Note: this were made before introducing the real time visualizer +``` goos: linux goarch: amd64 pkg: github.com/ESilva15/BeamNGMockOg/mockserver @@ -50,3 +46,16 @@ cpu: AMD Ryzen 5 5600G with Radeon Graphics BenchmarkReplayAsync-12 1 109433931841 ns/op 356088 B/op 13272 allocs/op PASS ok github.com/ESilva15/BeamNGMockOg/mockserver 109.440s +``` + + +#### Current results +``` +goos: linux +goarch: amd64 +pkg: github.com/ESilva15/BeamNGMockOg/mockserver +cpu: AMD Ryzen 7 5800X3D 8-Core Processor +BenchmarkReplayAsync-16 1 109433890158 ns/op 1673128 B/op 112986 allocs/op +PASS +ok github.com/ESilva15/BeamNGMockOg/mockserver 109.439s +``` diff --git a/mockserver/record.go b/mockserver/record.go index 89b0cfa..e49436d 100644 --- a/mockserver/record.go +++ b/mockserver/record.go @@ -1,11 +1,11 @@ package mockserver import ( + "bytes" "context" "encoding/binary" "fmt" "os" - "strings" "sync" "time" @@ -77,26 +77,28 @@ func (r *Recorder) record(ctx context.Context) { } func (r *Recorder) view(ctx context.Context) { - var s strings.Builder + var buf bytes.Buffer var nBytes int + buf.Grow(2048) + for { select { case <-ctx.Done(): return case viewData := <-r.viewCh: - s.Reset() - fmt.Fprintf(os.Stdout, "\x1b[2J\x1b[H") + buf.Reset() + buf.WriteString("\x1b[2J\x1b[H") - stringifyRecordingProgress(&s, nBytes) - fmt.Fprintf(&s, "\n\n") + stringifyRecordingProgress(&buf, nBytes) + fmt.Fprintf(&buf, "\n\n") r.viewDataMut.RLock() nBytes = viewData.TotalBytes - stringifyOutgaugeData(&s, &r.SDK) + stringifyOutgaugeData(&buf, &r.SDK) r.viewDataMut.RUnlock() - fmt.Fprint(os.Stdout, s.String()) + _, _ = buf.WriteTo(os.Stdout) } } } diff --git a/mockserver/replay.go b/mockserver/replay.go index 778a1aa..8d7b2c6 100644 --- a/mockserver/replay.go +++ b/mockserver/replay.go @@ -9,7 +9,6 @@ import ( "fmt" "io" "os" - "strings" "sync" "time" "unsafe" @@ -69,33 +68,34 @@ func (r *Replayer) renderToTerminal(ctx context.Context) { // return fmt.Errorf("error stating file: %v", err) } - // NOTE: temporary until I make a better view - var s strings.Builder + var buf bytes.Buffer var bytesReader bytes.Reader + buf.Grow(2048) + for { select { case <-ctx.Done(): return case data := <-r.dataViewCh: // Reset to the start of the terminal - s.Reset() - fmt.Fprintf(os.Stdout, "\x1b[2J\x1b[H") + buf.Reset() + buf.WriteString("\x1b[2J\x1b[H") bytesReader.Reset(data.SDK.Buffer) err := binary.Read(&bytesReader, binary.LittleEndian, r.SDK.Data) if err != nil { - fmt.Fprintf(&s, "FAILED TO PARSE DATA\nError: %+v", err) - fmt.Fprint(os.Stdout, s.String()) + fmt.Fprintf(&buf, "FAILED TO PARSE DATA\nError: %+v", err) + _, _ = buf.WriteTo(os.Stdout) continue } percent := int(float64(data.SizeRead) / float64(fileInfo.Size()) * 100) - fmt.Fprintf(&s, "Replayed: %d%%\n", percent) + fmt.Fprintf(&buf, "Replayed: %d%%\n", percent) - stringifyOutgaugeData(&s, data.SDK) + stringifyOutgaugeData(&buf, data.SDK) - fmt.Fprint(os.Stdout, s.String()) + buf.WriteTo(os.Stdout) } } } diff --git a/mockserver/views.go b/mockserver/views.go index e943b38..d508b10 100644 --- a/mockserver/views.go +++ b/mockserver/views.go @@ -1,8 +1,8 @@ package mockserver import ( + "bytes" "fmt" - "strings" bngsdk "github.com/ESilva15/gobngsdk" ) @@ -14,7 +14,7 @@ const ( GiB ) -func stringifyRecordingProgress(s *strings.Builder, nBytes int) { +func stringifyRecordingProgress(s *bytes.Buffer, nBytes int) { if nBytes < KiB { fmt.Fprintf(s, "%d B", nBytes) } else if nBytes < MiB { @@ -26,7 +26,7 @@ func stringifyRecordingProgress(s *strings.Builder, nBytes int) { } } -func stringifyOutgaugeData(s *strings.Builder, sdk *bngsdk.BeamNGSDK) { +func stringifyOutgaugeData(s *bytes.Buffer, sdk *bngsdk.BeamNGSDK) { // NOTE: write a string serialization function on the SDK itself fmt.Fprint(s, "Outgauge {\n") fmt.Fprintf(s, " Time: %d ms\n", sdk.Data.Time)