Up to Main Index                             Up to Journal for April, 2019

                     JOURNAL FOR SUNDAY 21ST APRIL, 2019
______________________________________________________________________________

SUBJECT: GET and DROP commands reimplemented with matcher
   DATE: Sun 21 Apr 18:28:40 BST 2019

I’ve been busy coding away, implementing new versions of the GET and DROP
commands that use the new matcher code. One thing that has been bothering me
is performance. The new matcher code is now doing a lot more processing to
identify which items you might mean for a given command.

To gain a measure of how bad it might be I hacked a quick and dirty TTP (time
to process) measurement into the state.Parse function. It simply times how
long it takes for a user issued command to be processed:


  func Parse(t has.Thing, input string) string {
    var ttps, ttpe time.Time
    ttps = time.Now()
    s := newState(t, input)
    for !s.sync() {
    }
    ttpe = time.Now()
    log.Printf("TTP: %s for %q", ttpe.Sub(ttps), input)
    return s.cmd
  }


Here are some example times for walking around the tavern in a square starting
at the fireplace, sneezing, examining the fire, inspecting our inventory and
playing with some items:


  TTP: 209.317µs for "south"
  TTP: 168.855µs for "east"
  TTP: 151.303µs for "north"
  TTP: 207.46µs  for "west"
  TTP: 191.103µs for "look"
  TTP: 169.734µs for "sneeze"
  TTP: 117.406µs for "exam fire"
  TTP: 111.402µs for "inv"
  TTP: 136.588µs for "exam chest"
  TTP: 136.034µs for "take pouch chest"
  TTP: 122.603µs for "exam pouch"
  TTP: 160.596µs for "take ball pouch"
  TTP: 122.122µs for "inv"


For some perspective, 100µs (microseconds) is 0.0001 or 1/10,000 seconds.

It would be nice so say that this means we could process 5,000 commands a
second. However, networking and resource locking would reduce this figure and
multiple CPU cores would increase this figure. So it’s quite hard to say for
sure how many commands a second we could actually process.

I implemented the new versions of GET and DROP as XGET and XDROP so that I
could easily compare them. The results surprised me:


  TTP: 126.239µs for "get lattice"
  TTP: 79.871µs  for "drop lattice"
  TTP: 34.969µs  for "xget lattice"
  TTP: 28.369µs  for "xdrop lattice"


The new versions were doing more, but actually faster. I tried something more
complex:


  TTP: 219.856µs for "xget lattice chest bag sack"
  TTP: 125.83µs  for "xdrop lattice chest bag sack"
  TTP: 184.992µs for "xget all ball"
  TTP: 141.056µs for "xdrop all ball"


This is actually getting and dropping four items at a time. In the first
instance four individually specified items. In the second instance four balls.
I replicated the first instance with the old commands:


    TTP: 146.302µs for "get lattice"
    TTP:  69.22 µs for "get chest"
    TTP:  49.296µs for "get bag"
    TTP:  35.468µs for "get sack"
  Total: 300.286µs (xget 219.856µs)
    TTP:  42.396µs for "drop lattice"
    TTP:  47.698µs for "drop chest"
    TTP:  45.318µs for "drop bag"
    TTP:  36.971µs for "drop sack"
  Total: 172.383µs (xdrop 141.056µs)


The new versions were still better performing :)

I need to sort out some proper benchmarking — and tests — for the commands,
but these quick and dirty timings are encouraging. So much so that I’ve now
replaced the existing GET and DROP commands with the new XGET and XDROP
commands. If you want to have a play changes are now on the public dev branch.

--
Diddymus


  Up to Main Index                             Up to Journal for April, 2019