Last active
November 29, 2021 19:14
-
-
Save nrdvana/7b5724745f553a22860589aa45a51edd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env perl | |
use strict; | |
use warnings; | |
use Benchmark qw( :hireswallclock cmpthese ); | |
{ | |
package OP_Point; | |
use v5.26; | |
use Object::Pad; | |
class OP_Point { | |
has $x :param :accessor = 0; | |
has $y :param :accessor = 0; | |
method move { | |
$x += $_[0]; | |
$y += $_[1]; | |
} | |
} | |
} | |
{ | |
package Moo_Point; | |
use v5.26; | |
use Class::XSAccessor; | |
use Moo; | |
has x => is => 'rw'; | |
has y => is => 'rw'; | |
sub move { | |
$_[0]->x($_[0]->x + $_[1]); | |
$_[0]->y($_[0]->y + $_[2]); | |
} | |
} | |
{ | |
package XSA_Point; | |
use v5.26; | |
use Class::XSAccessor | |
constructor => "new", | |
accessors => ["x","y"]; | |
sub move { | |
$_[0]->x($_[0]->x + $_[1]); | |
$_[0]->y($_[0]->y + $_[2]); | |
} | |
} | |
{ | |
package XSAA_Point; | |
use v5.26; | |
use Class::XSAccessor::Array | |
accessors => { x => 0, y => 1 }; | |
sub new { my $class= shift; my %p= @_; bless [$p{x}, $p{y}], $class; } | |
sub move { | |
$_[0]->x($_[0]->x + $_[1]); | |
$_[0]->y($_[0]->y + $_[2]); | |
} | |
} | |
{ | |
package PP_Point; | |
use v5.26; | |
sub new { | |
bless { @_[1..$#_] }, $_[0] | |
} | |
sub x { $_[0]{x}= $_[1] if @_ > 1; $_[0]{x} } | |
sub y { $_[0]{y}= $_[1] if @_ > 1; $_[0]{y} } | |
sub move { | |
$_[0]{x}+= $_[1]; | |
$_[0]{y}+= $_[2]; | |
} | |
} | |
{ | |
package PPA_Point; | |
use v5.26; | |
sub new { | |
my ($class, %p)= @_; | |
bless [ $p{x}, $p{y} ], $class; | |
} | |
sub x { $_[0][0]= $_[1] if @_ > 1; $_[0][0] } | |
sub y { $_[0][1]= $_[1] if @_ > 1; $_[0][1] } | |
sub move { | |
$_[0][0] += $_[1]; | |
$_[0][1] += $_[2]; | |
} | |
} | |
cmpthese(1000000, { | |
OP_Point => 'my $p= OP_Point->new(x => 10, y => 10); $p->move(1,1) for 1..3; ($p->x, $p->y) for 1..10', | |
Moo_Point => 'my $p= Moo_Point->new(x => 10, y => 10); $p->move(1,1) for 1..3; ($p->x, $p->y) for 1..10', | |
XSA_Point => 'my $p= XSA_Point->new(x => 10, y => 10); $p->move(1,1) for 1..3; ($p->x, $p->y) for 1..10', | |
XSAA_Point=> 'my $p= XSAA_Point->new(x => 10, y => 10);$p->move(1,1) for 1..3; ($p->x, $p->y) for 1..10', | |
PP_Point => 'my $p= PP_Point->new(x => 10, y => 10); $p->move(1,1) for 1..3; ($p->x, $p->y) for 1..10', | |
PPA_Point => 'my $p= PPA_Point->new(x => 10, y => 10); $p->move(1,1) for 1..3; ($p->x, $p->y) for 1..10', | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
My Results:
For some analysis, Cass::XSAccessor::Array doesn't have an XS constructor, so I had to write one in pure-perl. This is probably why it shows in the benchmark as slower than Class::XSAccessor. I picked the loop numbers as a rough estimate of how someone would use a point: create it, perform some translations on it, then use its coordinates a few times. Adjusting those loop numbers can give you a feel for how much constructor, method, and accessor play into the overall performance.
Moo is documented to use Class::XSAccessor when available, but I didn't verify whether it is doing this.
It's also worth noting that Moo_Point, XSA_Point, and XSAA_Point could all run faster if I used direct field access instead of accessors inside of the move() method. But OP_Point is already using it's fastest field access...