github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/physicscompress/main.go (about)

     1  // +build ignore
     2  
     3  // Response to Data Compression Challenge
     4  // http://gafferongames.com/2015/03/14/the-networked-physics-data-compression-challenge/
     5  /*
     6  #2831 265.434kbps ±127.341kbps
     7  
     8  MIN      2.880 kbps
     9  P05      6.240 kbps
    10  P10     82.080 kbps
    11  P25    182.400 kbps
    12  P50    272.640 kbps
    13  P75    355.680 kbps
    14  P90    426.720 kbps
    15  P95    472.320 kbps
    16  MAX    543.360 kbps
    17  
    18  TOTAL   12524.072 kb
    19    AVG       4.424 kb per frame
    20    AVG       1.563 bits per cube
    21  
    22  TIMING:
    23                    MIN        10%        25%        50%        75%        90%        MAX
    24      encode   21.885µs  228.686µs  414.047µs  596.281µs  774.495µs  923.677µs 1.724526ms
    25      decode   18.312µs  215.286µs  392.607µs  567.695µs   739.21µs  887.498µs 1.521745ms
    26  */
    27  package main
    28  
    29  import (
    30  	"bufio"
    31  	"flag"
    32  	"fmt"
    33  	"io"
    34  	"os"
    35  	"runtime"
    36  
    37  	"github.com/egonelbre/exp/physicscompress/physics"
    38  	"github.com/egonelbre/exp/qpc"
    39  
    40  	"github.com/montanaflynn/stats"
    41  )
    42  
    43  func main() {
    44  	verbose := flag.Bool("v", false, "verbose output")
    45  	flag.Parse()
    46  
    47  	file, err := os.Open("delta_data.bin")
    48  	check(err)
    49  	defer file.Close()
    50  
    51  	buffer := bufio.NewReader(file)
    52  
    53  	sizes := make([]float64, 0)
    54  	speeds := make([]float64, 0)
    55  
    56  	encode := qpc.NewHistory("encode")
    57  	decode := qpc.NewHistory("decode")
    58  
    59  	server := physics.NewState(901)
    60  	client := physics.NewState(901)
    61  
    62  	// initialize the base state
    63  	for i := 0; i < 6; i += 1 {
    64  		server.ReadNext(buffer)
    65  		client.IncFrame()
    66  		client.Current().Assign(server.Current())
    67  	}
    68  
    69  	frame := 6
    70  	for {
    71  		err = server.ReadNext(buffer)
    72  		if err == io.EOF {
    73  			break
    74  		}
    75  		check(err)
    76  		frame += 1
    77  
    78  		runtime.GC()
    79  
    80  		// Server side
    81  		encode.Start()
    82  		snapshot := server.Encode()
    83  		encode.Stop()
    84  		// ===
    85  
    86  		runtime.GC()
    87  
    88  		// Client side
    89  		decode.Start()
    90  		client.IncFrame()
    91  		client.Decode(snapshot)
    92  		decode.Stop()
    93  		// ===
    94  
    95  		size := float64(len(snapshot)*8) / 1000.0
    96  		sizes = append(sizes, size)
    97  
    98  		speed := size * 60.0
    99  		speeds = append(speeds, speed)
   100  
   101  		equal := server.Current().Equals(client.Current())
   102  		if *verbose {
   103  			if !equal {
   104  				fmt.Print("! ")
   105  			}
   106  			fmt.Printf("%04d %8.3fkbps %10s %10s\n", frame, speed, encode.Last(), decode.Last())
   107  		} else {
   108  			if equal {
   109  				fmt.Print(".")
   110  			} else {
   111  				fmt.Print("X")
   112  			}
   113  		}
   114  	}
   115  
   116  	fmt.Println()
   117  	fmt.Printf("#%d %.3fkbps ±%.3fkbps\n", len(sizes), stats.Mean(speeds), stats.StdDevS(speeds))
   118  	fmt.Println()
   119  
   120  	fmt.Printf("MIN %10.3f kbps\n", stats.Min(speeds))
   121  	for _, p := range []float64{5, 10, 25, 50, 75, 90, 95} {
   122  		fmt.Printf("P%02.f %10.3f kbps\n", p, stats.Percentile(speeds, p))
   123  	}
   124  	fmt.Printf("MAX %10.3f kbps\n", stats.Max(speeds))
   125  
   126  	fmt.Println()
   127  
   128  	fmt.Printf("TOTAL  %10.3f kb\n", stats.Sum(sizes))
   129  	fmt.Printf("  AVG  %10.3f kb per frame\n", stats.Mean(sizes))
   130  	fmt.Printf("  AVG  %10.3f bits per cube\n", stats.Mean(sizes)*1000/float64(len(sizes)))
   131  
   132  	fmt.Println()
   133  	fmt.Println("TIMING:")
   134  	qpc.PrintSummary(encode, decode)
   135  }
   136  
   137  func check(err error) {
   138  	if err != nil {
   139  		panic(err)
   140  	}
   141  }