Skip to content

Instantly share code, notes, and snippets.

@nihen
Created September 28, 2012 18:46
Show Gist options
  • Save nihen/3801485 to your computer and use it in GitHub Desktop.
Save nihen/3801485 to your computer and use it in GitHub Desktop.
teng_vs_skinny_vs_dbic_vs_dbi
# insert ok 1 - teng ok 2 - skinny ok 3 - dbi ok 4 - dbic # fast_insert ok 5 - teng ok 6 - skinny ok 7 - dbi ok 8 - dbic # single ok 9 - teng ok 10 - skinny ok 11 - dbi ok 12 - dbic # lookup ok 13 - teng ok 14 - skinny ok 15 - dbi ok 16 - dbic # search ok 17 - teng ok 18 - skinny ok 19 - dbi ok 20 - dbic # search_by_sql ok 21 - teng ok 22 - skinny ok 23 - dbi # dbic is not support search_by_sql # search_named ok 24 - teng ok 25 - skinny # dbi is not support search_named # dbic is not support search_named 1..25 DBI: 1.622 DBIx::Class version: 0.08200 Skinny version: 0.0742 Teng version: 0.15 --- insert --- Rate dbic teng skinny dbi dbic 941/s -- -17% -35% -45% teng 1131/s 20% -- -21% -34% skinny 1437/s 53% 27% -- -16% dbi 1706/s 81% 51% 19% -- --- fast_insert --- Rate dbic skinny teng dbi dbic 950/s -- -32% -38% -45% skinny 1399/s 47% -- -9% -19% teng 1540/s 62% 10% -- -11% dbi 1722/s 81% 23% 12% -- --- single --- Rate dbic skinny teng dbi dbic 1810/s -- -58% -63% -83% skinny 4325/s 139% -- -11% -60% teng 4876/s 169% 13% -- -55% dbi 10882/s 501% 152% 123% -- --- lookup --- Rate dbic skinny teng dbi dbic 1600/s -- -61% -76% -85% skinny 4072/s 155% -- -39% -62% teng 6720/s 320% 65% -- -38% dbi 10860/s 579% 167% 62% -- --- search --- Rate dbic skinny teng dbi dbic 950/s -- -42% -58% -83% skinny 1630/s 72% -- -28% -70% teng 2268/s 139% 39% -- -58% dbi 5440/s 473% 234% 140% -- --- search_by_sql --- Rate skinny teng dbi skinny 1879/s -- -28% -66% teng 2619/s 39% -- -53% dbi 5547/s 195% 112% -- --- search_named --- Rate skinny teng skinny 1777/s -- -27% teng 2419/s 36% --
#!/usr/bin/env perl
use strict;
use warnings;
use Benchmark qw(cmpthese);
use DBI;
use Test::More;
{
package DBIC::Schema::Result::User;
use base qw/DBIx::Class::Core/;
__PACKAGE__->table('user');
__PACKAGE__->add_columns(qw/id hoge/);
__PACKAGE__->set_primary_key('id');
package DBIC::Schema;
use base qw/DBIx::Class::Schema/;
__PACKAGE__->load_namespaces();
}
{
package SKN;
use DBIx::Skinny;
package SKN::Schema;
use DBIx::Skinny::Schema;
install_table user => schema {
pk 'id';
columns qw/id hoge/;
};
package SKN::Row::User;
use parent 'DBIx::Skinny::Row';
}
{
package TNG;
use parent 'Teng';
__PACKAGE__->load_plugin('Lookup');
package TNG::Schema;
use Teng::Schema::Declare;
table {
name "user";
pk "id";
columns qw/id hoge/;
};
}
unlink 'dbi.db' if -f 'dbi.db';
unlink 'dbic.db' if -f 'dbic.db';
unlink 'skn.db' if -f 'skn.db';
unlink 'tng.db' if -f 'tng.db';
my $table = 'create table user (id int primary key,hoge text)';
my $dbi = DBI->connect('dbi:SQLite:./dbi.db','','');
$dbi->do($table);
my $dbic = DBIC::Schema->connect('dbi:SQLite:./dbic.db','','');
$dbic->storage->dbh->do($table);
my $skn = SKN->new;
$skn->set_dbh(DBI->connect('dbi:SQLite:./skn.db','',''));
$skn->do($table);
my $tng = TNG->new(dbh => DBI->connect('dbi:SQLite:./tng.db','',''));
$tng->do($table);
our $dbi_user_id = 1;
our $dbic_user_id = 1;
our $skn_user_id = 1;
our $tng_user_id = 1;
my $methods = [qw/insert fast_insert single lookup search search_by_sql search_named/];
my $subs = {
'dbi' => {
get_result => sub {
my $method = shift;
[ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_]
},
insert => sub {
$dbi->do('INSERT INTO user (id, hoge) VALUES(?, ?)', undef, $dbi_user_id, 'moge');
+{id => $dbi_user_id++, hoge => 'moge'}
},
fast_insert => sub {
$dbi->do('INSERT INTO user (id, hoge) VALUES(?, ?)', undef, $dbi_user_id, 'moge');
$dbi_user_id++
},
single => sub {
$dbi->selectrow_hashref('SELECT id, hoge FROM user WHERE id = ?', undef, 1);
},
lookup => sub {
$dbi->selectrow_hashref('SELECT id, hoge FROM user WHERE id = ?', undef, 1);
},
search => sub {
$dbi->selectall_arrayref('SELECT id, hoge FROM user LIMIT 20', +{Slice => {}});
},
search_by_sql => sub {
$dbi->selectall_arrayref('SELECT id, hoge FROM user LIMIT 20', +{Slice => {}});
},
},
'dbic' => {
get_result => sub {
my ($method) = shift;
if ( $method eq 'fast_insert' ) {
return [$_[0]];
}
[map {+{$_->get_columns}} (ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_)]
},
insert => sub {
$dbic->resultset('User')->create({ id => $dbic_user_id++, hoge => 'moge' })
},
fast_insert => sub {
$dbic->resultset('User')->create({ id => $dbic_user_id++, hoge => 'moge' })->id
},
single => sub {
$dbic->resultset('User')->single({id => 1});
},
lookup => sub {
$dbic->resultset('User')->find(1);
},
search => sub {
[$dbic->resultset('User')->search({}, { rows => 20 })]
},
},
'skinny' => {
get_result => sub {
my ($method) = shift;
if ( $method eq 'fast_insert' ) {
return [$_[0]];
}
[map {$_->get_columns} (ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_)]
},
insert => sub {
$skn->insert(user => { id => $skn_user_id++, hoge => 'moge' })
},
fast_insert => sub {
$skn->insert(user => { id => $skn_user_id++, hoge => 'moge' })->id
},
single => sub {
$skn->single(user => { id => 1 } );
},
lookup => sub {
$skn->single(user => { id => 1 } );
},
search => sub {
[$skn->search(user => {}, { limit => 20 })]
},
search_by_sql => sub {
[$skn->search_by_sql('SELECT id, hoge FROM user LIMIT 20')]
},
search_named => sub {
[$skn->search_named('SELECT id, hoge FROM user where id < :id LIMIT 20', {id => 20})]
},
},
'teng' => {
get_result => sub {
my ($method) = shift;
if ( $method eq 'fast_insert' ) {
return [$_[0]];
}
[map {$_->get_columns} (ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_)]
},
insert => sub {
$tng->insert(user => { id => $tng_user_id++, hoge => 'moge' })
},
fast_insert => sub {
$tng->fast_insert(user => { id => $tng_user_id++, hoge => 'moge' })
},
single => sub {
$tng->single(user => { id => 1 } );
},
lookup => sub {
$tng->lookup(user => +{ id => 1 } );
},
search => sub {
[$tng->search(user => {}, { limit => 20 })]
},
search_by_sql => sub {
[$tng->search_by_sql('SELECT id, hoge FROM user LIMIT 20')]
},
search_named => sub {
[$tng->search_named('SELECT id, hoge FROM user where id < :id LIMIT 20', {id => 20})]
},
},
};
for my $method (@$methods) {
diag "$method\n";
my $results = {};
my $first;
for my $orm ( keys %$subs ) {
my $sub = $subs->{$orm}{$method};
unless ( $sub ) {
diag "$orm is not support $method";
next;
}
$results->{$orm} = $subs->{$orm}{get_result}->($method, $sub->());
if ( !$first ) {
$first = $results->{$orm};
ok $first, $orm;
}
else {
is_deeply $first => $results->{$orm}, $orm;
}
}
}
done_testing;
print "\n";
print "DBI: $DBI::VERSION\n";
print "DBIx::Class version: $DBIx::Class::VERSION\n";
print "Skinny version: $DBIx::Skinny::VERSION\n";
print "Teng version: $Teng::VERSION\n";
for my $method (@$methods) {
print "\n--- $method ---\n";
my $args = +{};
for my $orm ( keys %$subs ) {
if ( $subs->{$orm}{$method} ) {
$args->{$orm} = $subs->{$orm}{$method};
}
}
cmpthese(-1, $args);
}
__END__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment