Anacronia on speed
Upcoming SlideShare
Loading in...5
×
 

Anacronia on speed

on

  • 522 views

Presentation given at the Glasgow Perl Mongers a while ago, about how I sped up part of my Multi User Dungeon written in Perl, and some lessons learnt from it

Presentation given at the Glasgow Perl Mongers a while ago, about how I sped up part of my Multi User Dungeon written in Perl, and some lessons learnt from it

Statistics

Views

Total Views
522
Views on SlideShare
521
Embed Views
1

Actions

Likes
0
Downloads
0
Comments
0

1 Embed 1

http://www.docshut.com 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Anacronia on speed Anacronia on speed Presentation Transcript

  • MUD on speed Marco Fontani – Glasgow.pm - 2011-05-12
  • MUD on speed A journey I failed to talk about yet, about Perl, MUDs, strings, Gentoos, and other funny characters. And some who think they are funny.
  • Back in '99...
    • Multi User Dungeon, written in C
    • ~20 italian users logged in most evenings
    • V2, rewrite - still in C
    • V3, attempted rewrite in C++ merging code from another developer who joined
    • Came to Scotland.. no v4 for a while.
  • Anacronia v4
    • Perl, Moose, POE
    • speed/workflow fake user tests
    • Handled ~20/30 (fake) users constantly submitting output-intensive commands (admittedy with zlib compression)
    • A select loop in 1999 handled more
  • Anacronia v4 – second attempt
    • Class::XSAccessor, EV, AnyEvent, Gearman
    • speed/workflow fake user tests
    • Now handles a hell of a lot of users, asynchronously, making db connections, using background tasks, etc.
    • But let's not get ahead of ourselves
  • NYTProf
      Back when the MUD ran on POE, I profiled it Since most of the time the fake users were receiving output, it's sensible to expect time to be mostly spent on the output subs Nay, it was spent mostly on one sub The others came way after it
  • MUD ANSI encoding
      People liked colours in 1999, and they still do They didn't like raw ANSI, and they still do not e[31mREDe[30mreset vs. &rRED&w
  • MUD ANSI encoding
      The letters are x, r, g, y, b, p, c, w for black/reset, red, green, yellow and so on Uppercase makes bold, etc. --^p&WA&yn&Wa&yc&Wr&yo&Wn&yi&Wa &CV4&^--
  • From &r to e[31m
      sub ansify { my ($string, $previous_ansi_state) = @_; # … my @str = unpack('C*',$string); for my $i ( 0 .. $#str ) { # …; if after a '&' then check/get char color my $newcol = getcolor ($str[$i]); # … construct ansi, blah blah
  • Sub getcolor, rev. 1
      { my @colors = map { ord } qw/x r g y b p c w/; sub perl_getcolor { my $clrchar = shift; for ( 0 .. $#colors ) { return $_ if ( $clrchar == $colors[$_] ); return $_ if ( ( $clrchar + 32 ) == $colors[$_] ); } return 255; } } # Pure Perl version 34262/s
  • Sub getcolor, rev. 2
      { # -funroll-loops for the Gentooist enthusiasts sub opt_perl_getcolor { $_[0] == 120 && return 0; $_[0] == 88 && return 0; $_[0] == 114 && return 1; $_[0] == 82 && return 1; $_[0] == 103 && return 2; $_[0] == 71 && return 2; $_[0] == 121 && return 3; $_[0] == 89 && return 3; $_[0] == 98 && return 4; $_[0] == 66 && return 4; $_[0] == 112 && return 5 $_[0] == 80 && return 5; $_[0] == 99 && return 6; $_[0] == 67 && return 6; $_[0] == 119 && return 7; $_[0] == 87 && return 7; return 255; } } # 98814/s, ~3x faster
  • The MUD version
      When I find my code in tons of trouble, Friends and colleagues come to me, Speaking words of wisdom: "Write in C."
  • The MUD version
      Inline::C, Inline::C Inline::C, oh, Inline::C. Pure Perl won't quite cut it. Inline::C.
  • Sub getcolor, “live”
      use Inline C => <<'END_INLINE_C'; unsigned char __colors[8] = &quot;xrgybpcw&quot;; unsigned char getcolor(unsigned char clrchar) { char i = 0; for ( i = 0; i < 8; i++ ) { if ( clrchar == __colors[i] ) { return i; } if ( ( clrchar+32) == __colors[i] ) { return i; } } return (unsigned char) -1; } END_INLINE_C # Inline::C version 337079/s # 10x faster than the pure-perl one
  • That's all folks!
  • That's all folks!
      … right?
  • That's all folks!
  • That's all folks!
      I blogged about it, and got some suggestions:
    • Use hash lookups
    • Use (faster) tr
    • Use (much faster) array lookups
    • Use $_[0] for speed
    • Use map, join and quotemeta
    • -funroll-loops the Inline::C version (that was me!)
  • Who wins?
      http://darkpan.com/files/ansi--inline-c--vs--perl.pl.txt Rate Pure Perl Opt Perl Hash Perl Lookup Perl Inline::C Opt Inline::C Pure Perl 35294/s -- -67% -76% -80% -90% -91% Opt Perl 106157/s 201% -- -27% -39% -71% -74% Hash Perl 146056/s 314% 38% -- -16% -60% -65% Lookup Perl 174216/s 394% 64% 19% -- -52% -58% Inline::C 363196/s 929% 242% 149% 108% -- -12% Opt Inline::C 412088/s 1068% 288% 182% 137% 13% -- The array lookup is indeed only ½ the speed of Inline::C but Pure Perl The unrolled loops Inline::C version is made of win, though ;)
    • There is more than one way to shave a yak
    • one more thing
  • “You could've simply memoized the conversions”
    • use Memoize; memoize('sub_name');
    • It's in CORE
    • It's designed for helping with similar problems
    • It usually works
  • Marco, why don't you use Memoize?
    • In this case, because it sucks.
    • Rate Memoized Pure Perl Pure Perl
    • Memoized Pure Perl 15012/s -- -54%
    • Pure Perl 32573/s 117% --