Up to Main Index                              Up to Journal for June, 2019

                     JOURNAL FOR THURSDAY 20TH JUNE, 2019
______________________________________________________________________________

SUBJECT: You asked for an improved matcher…
   DATE: Thu 20 Jun 18:10:04 BST 2019

It’s been a while since my last entry, however I’ve not been idle — I’ve been
busy quietly working away on WolfMUD. A number of people have commented on the
matcher and pointed out that it wasn’t up to my usual standards. It was
described to me as “a blob of code that’s hard to decipher”. I whole heartedly
agreed with that assessment and decided to do something about it.

Initially the matcher was a hastily hacked together experiment. As the
experiment seemed quite successful I ran with the code, attempting several
times to clean it up and improve performance. No dice. What it really needed
was a complete overhaul, a rewrite — now that the requirements were better
understood.

The rewrite was completed within a few evenings. However, performance was
horrendous compared to the original and there was still some ugliness in the
code. I persevered, convinced I was on the right track and doing the right
thing. I then spent my evenings over the next week iterating over the new
code. A small tweak here and there, benchmark, repeat. Benchmarking takes
about 2-3 minutes each time, you can’t do anything except sit and wait so as
not to skew the results.

The new matcher makes heavy use of filtering slices without allocating. This
is where you reuse the backing array of the slice you filtering as you iterate
over it:


  subset := results[:0]
  for _, r := range results {
    if r.Test() {
      subset = append(subset, r)
    }
  }
  results = results[:len(subset)]


Here the subset slice is reusing the backing array of the results slice. It
does mean that the original content of results will be overwritten.

The final result is… interesting. Performance is mostly improved and I’ve
reduced allocations in a lot of instances. For an idea of the current
performance here are some benchmarks:


  name                              old time/op    new time/op    delta
  MatchAll/#00-4                    13.3ns ± 0%     5.2ns ± 0%   -61.18%
  MatchAll/apple-4                  1.46µs ± 2%    1.76µs ± 2%   +20.65%
  MatchAll/ball-4                   1.63µs ± 1%    1.73µs ± 2%    +5.97%
  MatchAll/token-4                  1.44µs ± 1%    1.73µs ± 0%   +20.80%
  MatchAll/all_ball-4               3.28µs ± 0%    2.08µs ± 1%   -36.63%
  MatchAll/all_green_ball-4         3.42µs ± 1%    2.23µs ± 1%   -34.90%
  MatchAll/all_red_ball-4           3.43µs ± 1%    2.22µs ± 1%   -35.31%
  MatchAll/all_small_ball-4         3.47µs ± 2%    2.20µs ± 3%   -36.51%
  MatchAll/all_large_ball-4         3.44µs ± 1%    2.21µs ± 2%   -35.83%
  MatchAll/apple_ball_chalk-4       5.93µs ± 3%    6.05µs ± 1%    +1.96%
  MatchAll/apple_all_ball_chalk-4   7.42µs ± 2%    6.49µs ± 4%   -12.48%
  MatchAll/frog-4                   1.56µs ± 1%    1.75µs ± 1%   +12.33%
  MatchAll/apple_frog-4             3.29µs ± 3%    3.63µs ± 1%   +10.50%
  MatchAll/apple_frog_chalk-4       5.24µs ± 0%    5.67µs ± 2%    +8.11%
  MatchAll/a_b_c_d_e_f_g_h_i_j_k…   37.5µs ± 3%    46.7µs ± 5%   +24.46%
  Match/#00-4                       13.3ns ± 0%    13.9ns ± 0%    +4.25%
  Match/apple-4                     1.43µs ± 2%    1.73µs ± 1%   +20.50%
  Match/ball-4                      1.75µs ± 1%    1.73µs ± 1%    -1.35%
  Match/token-4                     1.44µs ± 1%    1.73µs ± 1%   +20.57%
  Match/all_ball-4                  3.67µs ± 1%    2.12µs ± 3%   -42.23%
  Match/all_green_ball-4            3.88µs ± 1%    2.17µs ± 1%   -44.03%
  Match/all_red_ball-4              3.72µs ± 1%    2.20µs ± 2%   -40.96%
  Match/all_small_ball-4            3.64µs ± 3%    2.21µs ± 2%   -39.31%
  Match/all_large_ball-4            3.62µs ± 2%    2.19µs ± 2%   -39.63%
  Match/apple_ball_chalk-4          1.70µs ± 1%    1.83µs ± 1%    +7.27%
  Match/apple_all_ball_chalk-4      1.72µs ± 3%    1.83µs ± 1%    +6.57%
  Match/frog-4                      1.43µs ± 3%    1.69µs ± 1%   +18.66%
  Match/apple_frog-4                1.51µs ± 3%    1.71µs ± 1%   +13.02%
  Match/apple_frog_chalk-4          1.79µs ± 2%    1.85µs ± 1%    +3.38%
  Match/a_b_c_d_e_f_g_h_i_j_k_l…    1.71µs ± 4%    1.64µs ± 1%    -3.99%

                                         old            new
  name                                allocs/op      allocs/op    delta
  MatchAll/#00-4                       0.00           0.00          ~
  MatchAll/apple-4                    12.0 ± 0%      13.0 ± 0%    +8.33%
  MatchAll/ball-4                     14.0 ± 0%      13.0 ± 0%    -7.14%
  MatchAll/token-4                    12.0 ± 0%      13.0 ± 0%    +8.33%
  MatchAll/all_ball-4                 24.0 ± 0%      13.0 ± 0%   -45.83%
  MatchAll/all_green_ball-4           25.0 ± 0%      13.0 ± 0%   -48.00%
  MatchAll/all_red_ball-4             25.0 ± 0%      13.0 ± 0%   -48.00%
  MatchAll/all_small_ball-4           25.0 ± 0%      13.0 ± 0%   -48.00%
  MatchAll/all_large_ball-4           25.0 ± 0%      13.0 ± 0%   -48.00%
  MatchAll/apple_ball_chalk-4         43.0 ± 0%      41.0 ± 0%    -4.65%
  MatchAll/apple_all_ball_chalk-4     49.0 ± 0%      41.0 ± 0%   -16.33%
  MatchAll/frog-4                     11.0 ± 0%      13.0 ± 0%   +18.18%
  MatchAll/apple_frog-4               23.0 ± 0%      27.0 ± 0%   +17.39%
  MatchAll/apple_frog_chalk-4         36.0 ± 0%      41.0 ± 0%   +13.89%
  MatchAll/a_b_c_d_e_f_g_h_i_j_k…      261 ± 0%       363 ± 0%   +39.08%
  Match/#00-4                          0.00           0.00          ~
  Match/apple-4                       12.0 ± 0%      13.0 ± 0%    +8.33%
  Match/ball-4                        14.0 ± 0%      13.0 ± 0%    -7.14%
  Match/token-4                       12.0 ± 0%      13.0 ± 0%    +8.33%
  Match/all_ball-4                    24.0 ± 0%      13.0 ± 0%   -45.83%
  Match/all_green_ball-4              25.0 ± 0%      13.0 ± 0%   -48.00%
  Match/all_red_ball-4                25.0 ± 0%      13.0 ± 0%   -48.00%
  Match/all_small_ball-4              25.0 ± 0%      13.0 ± 0%   -48.00%
  Match/all_large_ball-4              25.0 ± 0%      13.0 ± 0%   -48.00%
  Match/apple_ball_chalk-4            13.0 ± 0%      13.0 ± 0%      ~
  Match/apple_all_ball_chalk-4        13.0 ± 0%      13.0 ± 0%      ~
  Match/frog-4                        11.0 ± 0%      13.0 ± 0%   +18.18%
  Match/apple_frog-4                  11.0 ± 0%      13.0 ± 0%   +18.18%
  Match/apple_frog_chalk-4            13.0 ± 0%      13.0 ± 0%      ~
  Match/a_b_c_d_e_f_g_h_i_j_k_l…      11.0 ± 0%      13.0 ± 0%   +18.18%


There is one optimisation left that I would like to make to improve the
MatchAll function. Every time I try to implement it the code becomes a mess
again. Either that or performance takes a hit because of the setup and
bookkeeping involved. Still, I’m going to try one last time this evening and
if it doesn’t pan out leave it for now.

In the meantime the new code is out on the public dev branch.

--
Diddymus


  Up to Main Index                              Up to Journal for June, 2019