tsee/p5-ShardedKV — pull request #4 by dams (2014-01-15 14:15:45+00:00)
Title: use currying and a getter

While providing a PR to fix connection reset (issue was that connection wasn't reset when it should in SharedKv code) I saw that the code is bypassing Moose accessor to use things like $self->{stuff} instead of $self->stuff. That's for speed purpose ( my benchmark shows it's 20% faster than using accessors in this particular code).

However this is imho very dangerous. It basically vorbid anyone to build other modules to extend this one. method modifiers, triggers, attribute features are not going to work properly. Introspection and meta won't work either.

Here I propose a different approach, by using currying and some Moose attribute features so it uses accessors to build a Coderef specialized for a given instance. When this instance is changed (very rarely), for instance begin migration, extend shard, etc the Coderef is rebuilt, still using the accessors.

With my implementation, using ->get() is marginally faster than before. However, using my $getter = $self->getter; then later on doing $$getter->($key), is 50% faster. And it works well with migration etc, as the CoderRef can be rebuilt behind the scene.

I've provided a small benchmark in tools. Maybe it's not a fair benchmark, but I believe it is good enough. Here are the results (master implementation is "no_acc"):

Rate wit_acc no_acc indirect_getter direct_getter
wit_acc 236307/s -- -26% -30% -51%
no_acc 320145/s 35% -- -6% -34%
indirect_getter 338841/s 43% 6% -- -30%
direct_getter 486720/s 106% 52% 44% --