github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/physicscompress2/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  #2166 4016.563kbps ±1033.245kbps
     7  
     8  MIN   1268.640 kbps
     9  P05   1911.360 kbps
    10  P10   2352.000 kbps
    11  P25   3403.680 kbps
    12  P50   4261.200 kbps
    13  P75   5011.680 kbps
    14  P90   5044.800 kbps
    15  P95   5064.480 kbps
    16  MAX   5157.600 kbps
    17  
    18  TOTAL  144997.928 kb
    19    AVG      66.943 kb per frame
    20    AVG      30.906 bits per cube
    21  
    22  TIMING:
    23                    MIN        10%        25%        50%        75%        90%        MAX
    24      encode  6.37552ms 9.357373ms 10.939417ms 15.087927ms 16.153194ms 16.481931ms 21.978885ms
    25      decode 6.170953ms 9.100995ms 10.726811ms 14.926909ms 16.004459ms 16.347935ms 22.231691ms
    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/physicscompress2/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_round_two.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  }