SlideShare a Scribd company logo
1 of 81
About the dangers of refactoring




        Andrei Pratasavitski
           May Perl + Perl Mova
               2012-05-12
Refactoring
Code refactoring is a "disciplined technique
for restructuring an existing body of code,
altering its internal structure without changing
its external behavior" [Martin Fowler in
http://refactoring.com/], undertaken in order to
improve some of the nonfunctional attributes
of the software.

                                         Wikipedia
Рефакторинг
Рефакторинг или рефакторирование (англ.
refactoring) — процесс изменения
внутренней структуры программы, не
затрагивающий её внешнего поведения и
имеющий целью облегчить понимание её
работы.


                                RU.Wikipedia
Рефакторинг
Рефакторинг (англ. refactoring) —
перетворення програмного коду, зміна
внутрішньої структури програмного
забезпечення для полегшення розуміння
коду і легшого внесення подальших змін
без зміни зовнішньої поведінки самої
системи.

                                 UA.Wikipedia
Refactoring
●   Restructuring an
    existing body of
    code
●   Non-functional
●   Without changing
    its external
    behavior
THE AXIOM




Developers DO love refactoring
Refactoring
●   Makes developers'
    lives easy and
    happy
●   Brighter
●   Creates an illusion
    of hardworking
    brains
●   And...
And refactoring...
●   ...does

    NOTHING

    for users
Refactoring




What they want to do...           What they do...
Why is Refactoring a dirty word?
●   Writing code is easier than reading it.
●   So, “refactoring” often means “rewriting”.
●   Understanding code requires reading it.
●   How can you rewrite code that you don't
    understand?
●   Probably not very well...
You can't refactor the world...
●   The world is often a
    messy place.
●   If code deals with the real
    word it probably will be
    messy too.
●   Refactoring can't make
    the world less complex or
    messy.
Refactoring gone wrong
●   People tend to delete what
    they don't understand in the
    misguided hope that “it was
    not used”.
●   They do it too early, and too
    often. Its not like voting!
●   They tend to over
    generalize and violate
    YAGNI.
Refactoring has risks...
●   You might... break something
●   ... refactor the code in such a way that the
    maintainer doesn't understand.
●   ... annoy your colleagues
●   … refactor something for the wrong priority
●   … make the code harder to maintain
●   … waste time by treading water
(Thanks to Yves Orton)
Developer Craft
(December 2011)
This is what business says
This is what business says
Because          ...and

business         developers

wants            want

results...       beauty!
This is what business says
               ...and

               developers

               want

               beauty!
This is what business says
Code WTF
Code WTF
Code WTF
Code WTF
WTF
Code WTF
WTF       ●   Watch
Code WTF
WTF       ●   Watch
          ●   Think
Code WTF
WTF       ●   Watch
          ●   Think
          ●   Figure out
Code WTF
WTF       ●   Watch
          ●   Think
          ●   Figure out



               Philippe (BooK) Bruhat
Code evil is...
Code evil is...
●   ...map in void context
●   ...goto
●   ...repeating code
●   ...using properties instead of accessors
●   ...to not use foreign keys
●   ...to do on Perl side what DB can do
Code evil is...
●   ...map in void context
●   ...goto
●   ...repeating code
●   ...using properties instead of accessors
●   ...to not use foreign keys
●   ...to do on Perl side what DB can do
                       Why?
Because...
●   ...it looks ugly!
●   ...it is hard to read!
●   ...it is a bad practice!
●   ...it will bring benefits in the future!
●   ...there is another way to do it!
●   ...it sucks!
●   ...I don't like it!
But how about...




  ...performance?
map in void context
map in void context
use Benchmark qw(cmpthese);
my @arr;

my $times = 1_000_000;

sub ss { $_[0] =~ s/1/a/; }

cmpthese(
    $times,
    {
        map1   =>   sub   {   @arr   =   1..100;   map s/1/a/, @arr; },
        map2   =>   sub   {   @arr   =   1..100;   map { s/1/a/ } @arr; },
        map3   =>   sub   {   @arr   =   1..100;   map &ss($_), @arr; },
        map4   =>   sub   {   @arr   =   1..100;   map { &ss($_) } @arr; },
        for1   =>   sub   {   @arr   =   1..100;   for (@arr) { s/1/a/ }; },
        for2   =>   sub   {   @arr   =   1..100;   s/1/a/ for @arr; },
        for3   =>   sub   {   @arr   =   1..100;   do { s/1/a/ } for @arr; },
        for4   =>   sub   {   @arr   =   1..100;   for (@arr) { &ss($_) }; },
        for5   =>   sub   {   @arr   =   1..100;   &ss($_) for @arr; },
        for6   =>   sub   {   @arr   =   1..100;   do { &ss($_) } for @arr; },
        for7   =>   sub   {   @arr   =   1..100;   do &ss($_) for @arr; },
    }
);
map in void context
use Benchmark qw(cmpthese);
my @arr;

my $times = 1_000_000;

sub ss { $_[0] =~ s/1/a/; }

cmpthese(
    $times,
    {
        map1   =>   sub   {   @arr   =   1..100;   map s/1/a/, @arr; },
        map2   =>   sub   {   @arr   =   1..100;   map { s/1/a/ } @arr; },
        map3   =>   sub   {   @arr   =   1..100;   map &ss($_), @arr; },
        map4   =>   sub   {   @arr   =   1..100;   map { &ss($_) } @arr; },
        for1   =>   sub   {   @arr   =   1..100;   for (@arr) { s/1/a/ }; },
        for2   =>   sub   {   @arr   =   1..100;   s/1/a/ for @arr; },
        for3   =>   sub   {   @arr   =   1..100;   do { s/1/a/ } for @arr; },
        for4   =>   sub   {   @arr   =   1..100;   for (@arr) { &ss($_) }; },
        for5   =>   sub   {   @arr   =   1..100;   &ss($_) for @arr; },
        for6   =>   sub   {   @arr   =   1..100;   do { &ss($_) } for @arr; },
        for7   =>   sub   {   @arr   =   1..100;   do &ss($_) for @arr; },
    }
);
map in void context
use Benchmark qw(cmpthese);
my @arr;

my $times = 1_000_000;

sub ss { $_[0] =~ s/1/a/; }

cmpthese(
    $times,
    {
        map1   =>   sub   {   @arr   =   1..100;   map s/1/a/, @arr; },
        map2   =>   sub   {   @arr   =   1..100;   map { s/1/a/ } @arr; },
        map3   =>   sub   {   @arr   =   1..100;   map &ss($_), @arr; },
        map4   =>   sub   {   @arr   =   1..100;   map { &ss($_) } @arr; },
        for1   =>   sub   {   @arr   =   1..100;   for (@arr) { s/1/a/ }; },
        for2   =>   sub   {   @arr   =   1..100;   s/1/a/ for @arr; },
        for3   =>   sub   {   @arr   =   1..100;   do { s/1/a/ } for @arr; },
        for4   =>   sub   {   @arr   =   1..100;   for (@arr) { &ss($_) }; },
        for5   =>   sub   {   @arr   =   1..100;   &ss($_) for @arr; },
        for6   =>   sub   {   @arr   =   1..100;   do { &ss($_) } for @arr; },
        for7   =>   sub   {   @arr   =   1..100;   do &ss($_) for @arr; },
    }
);
map in void context
use Benchmark qw(cmpthese);
my @arr;

my $times = 1_000_000;

sub ss { $_[0] =~ s/1/a/; }

cmpthese(
    $times,
    {
        map1   =>   sub   {   @arr   =   1..100;   map s/1/a/, @arr; },
        map2   =>   sub   {   @arr   =   1..100;   map { s/1/a/ } @arr; },
        map3   =>   sub   {   @arr   =   1..100;   map &ss($_), @arr; },
        map4   =>   sub   {   @arr   =   1..100;   map { &ss($_) } @arr; },
        for1   =>   sub   {   @arr   =   1..100;   for (@arr) { s/1/a/ }; },
        for2   =>   sub   {   @arr   =   1..100;   s/1/a/ for @arr; },
        for3   =>   sub   {   @arr   =   1..100;   do { s/1/a/ } for @arr; },
        for4   =>   sub   {   @arr   =   1..100;   for (@arr) { &ss($_) }; },
        for5   =>   sub   {   @arr   =   1..100;   &ss($_) for @arr; },
        for6   =>   sub   {   @arr   =   1..100;   do { &ss($_) } for @arr; },
        for7   =>   sub   {   @arr   =   1..100;   do &ss($_) for @arr; },
    }
);
Results

        for7   map4   map3   for6   map2   for4   for5   for3   for1   for2   map1
for7      --   -91%   -91%   -93%   -93%   -94%   -94%   -95%   -95%   -96%   -96%
map4    963%     --    -5%   -26%   -29%   -32%   -33%   -45%   -52%   -52%   -53%
map3   1022%     6%     --   -22%   -25%   -28%   -29%   -42%   -49%   -50%   -51%
for6   1338%    35%    28%     --    -4%    -8%    -9%   -26%   -35%   -36%   -37%
map2   1396%    41%    33%     4%     --    -4%    -5%   -23%   -32%   -33%   -34%
for4   1461%    47%    39%     9%     4%     --    -1%   -20%   -29%   -30%   -32%
for5   1476%    48%    40%    10%     5%     1%     --   -19%   -29%   -30%   -31%
for3   1844%    83%    73%    35%    30%    25%    23%     --   -12%   -13%   -15%
for1   2110%   108%    97%    54%    48%    42%    40%    14%     --    -1%    -3%
for2   2137%   110%    99%    56%    49%    43%    42%    15%     1%     --    -2%
map1   2181%   115%   103%    59%    52%    46%    45%    17%     3%     2%     --
Results

        for7   map4   map3   for6   map2   for4   for5   for3   for1   for2   map1
for7      --   -91%   -91%   -93%   -93%   -94%   -94%   -95%   -95%   -96%   -96%
map4    963%     --    -5%   -26%   -29%   -32%   -33%   -45%   -52%   -52%   -53%
map3   1022%     6%     --   -22%   -25%   -28%   -29%   -42%   -49%   -50%   -51%
for6   1338%    35%    28%     --    -4%    -8%    -9%   -26%   -35%   -36%   -37%
map2   1396%    41%    33%     4%     --    -4%    -5%   -23%   -32%   -33%   -34%
for4   1461%    47%    39%     9%     4%     --    -1%   -20%   -29%   -30%   -32%
for5   1476%    48%    40%    10%     5%     1%     --   -19%   -29%   -30%   -31%
for3   1844%    83%    73%    35%    30%    25%    23%     --   -12%   -13%   -15%
for1   2110%   108%    97%    54%    48%    42%    40%    14%     --    -1%    -3%
for2   2137%   110%    99%    56%    49%    43%    42%    15%     1%     --    -2%
map1   2181%   115%   103%    59%    52%    46%    45%    17%     3%     2%     --
Results

cmpthese(
    $times,
    {
        for1 => sub { @arr = 1..100; for (@arr) { s/1/a/ }; },
        for2 => sub { @arr = 1..100; s/1/a/ for @arr; },
        map1 => sub { @arr = 1..100; map s/1/a/, @arr; },
    }
);

       for1 for2 map1
for1     -- -1% -4%
for2     1%   -- -3%
map1     4%   3%   --
Results

cmpthese(
    $times,
    {
        for1 => sub { @arr = 1..100; for (@arr) { s/1/a/ }; },
        for2 => sub { @arr = 1..100; s/1/a/ for @arr; },
        map1 => sub { @arr = 1..100; map s/1/a/, @arr; },
    }
);

       for1 for2 map1
for1     -- -1% -4%
for2     1%   -- -3%
map1     4%   3%   --
map in void context


      ...is faster
map in void context


      ...is faster

        ...a bit
map in void context


      ...is faster

        ...a bit

     ...sometimes
map in void context

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Have a look at...

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Have a look at...

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Have a look at...

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Have a look at...

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Have a look at...

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Have a look at...

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Have a look at...

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Have a look at...

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Repeating code
Repeating code
my ($row, @rows)
my $tmp = $sth->fetchrow_hashref();
while ( $row = $sth->fetchrow_hashref() ) {
    if ( $row->{field} eq $tmp->{field} ) {
        push @rows, $row;
    }
    else {
        # do something with $tmp and @rows
        $tmp = $row;
    }
}
Repeating code
my ($row, @rows)
my $tmp = $sth->fetchrow_hashref();
while ( $row = $sth->fetchrow_hashref() ) {
    if ( $row->{field} eq $tmp->{field} ) {
        push @rows, $row;
    }
    else {
        # do something with $tmp and @rows
        $tmp = $row;
    }
}

# do something with $tmp and @rows
Repeating code
my ($row, @rows)
my $tmp = $sth->fetchrow_hashref();
while ( $row = $sth->fetchrow_hashref() ) {
    if ( $row->{field} eq $tmp->{field} ) {
        push @rows, $row;
    }
    else {
        &do_something($tmp, @rows);
        $tmp = $row;
    }
}

&do_something($tmp, @rows);
Repeating code

 1.   map1   |   2181%   |   map s/1/a/, @arr;
 2.   for2   |   2137%   |   s/1/a/ for @arr;
 3.   for1   |   2110%   |   for (@arr) { s/1/a/ };
 4.   for3   |   1844%   |   do { s/1/a/ } for @arr;
 5.   for5   |   1476%   |   &ss($_) for @arr;
 6.   for4   |   1461%   |   for (@arr) { &ss($_) };
 7.   map2   |   1396%   |   map { s/1/a/ } @arr;
 8.   for6   |   1338%   |   do { &ss($_) } for @arr;
 9.   map3   |   1022%   |   map &ss($_), @arr;
10.   map4   |    963%   |   map { &ss($_) } @arr;
11.   for7   |      0%   |   do &ss($_) for @arr;
Repeating code


  ...can be useful
Repeating code


              ...can be useful


...if you remember that method/function call
               is expensive
Properties instead of accessors
Properties instead of accessors




$request->stash(key => 'value');
Properties instead of accessors



my $stash = $request->stash();

$stash->{key} = 'value';
Properties instead of accessors



my $stash = $request->{stash};

$stash->{key} = 'value';
goto is evil?
goto is evil?




   Really?
goto is evil?

$ ack-grep -a '^s*gotos+' 
/usr/lib/perl/5.14/*.pm | wc -l
10
$ ack-grep -a '^s*gotos+' 
/usr/share/perl/5.14/*.pm | wc -l
29
goto is evil?


All those cases have

goto &somewhere;

   in AUTOLOAD
goto is evil?
goto is evil?




Yes, it's evil!
Do on Perl side what DB can do
Do on Perl side what DB can do
my @days = &days_from_period('2010-08-01', '2010-08-31');
# here @days = ('2010-08-01', '2010-08-01', '2010-08-01', ... '2010-08-31')

my %result = ();

my $sth = $dbh->prepare(<<'SQL');
SELECT SUM(amount) AS result
FROM Table t
    LEFT JOIN AnotherTable at USING(field)
    LEFT JOIN YetAnotherTable yat ON (...)
WHERE
    payday = ?
    AND (long_long_list_of_conditions)
SQL

for my $day (@days) {
    $sth->execute($day);
    $result{day} = $stf->fetchrow_arrayref()->[0] || 0;
}
# my @days = &days_from_period('2010-08-01', '2010-08-31');
# here @days = ('2010-08-01', '2010-08-01', '2010-08-01', ... '2010-08-31')

my %result = ();

# my $sth = $dbh->prepare(<<'SQL');
my $sql = <<'SQL';
SELECT
    payday,
    SUM(amount) AS result
FROM Table t
    LEFT JOIN AnotherTable at USING(field)
    LEFT JOIN YetAnotherTable yat ON (...)
WHERE
    payday BETWEEN ? AND ?
    AND (long_long_list_of_conditions)
GROUP BY payday
SQL

# for my $day (@days) {
#    $sth->execute($day);
#    $result{day} = $stf->fetchrow_arrayref()->[0] || 0;
    %result = $sth->selectall_hashref($sql, 'payday', undef,
                                      '2010-08-01', '2010-08-31');
# }
my %result = ();

my $sql = <<'SQL';
SELECT
    payday,
    SUM(amount) AS result
FROM Table t
    LEFT JOIN AnotherTable at USING(field)
    LEFT JOIN YetAnotherTable yat ON (...)
WHERE
    payday BETWEEN ? AND ?
    AND (long_long_list_of_conditions)
GROUP BY payday
SQL

%result = $sth->selectall_hashref($sql, 'payday', undef,
                                  '2010-08-01', '2010-08-31');
Do on Perl side what DB can do
Do on Perl side what DB can do

                                     SELECT
SELECT SUM(amount) AS result             payday,
FROM Table t                             SUM(amount) AS result
    LEFT JOIN AnotherTable at        FROM Table t
        USING(field)                     LEFT JOIN AnotherTable at
    LEFT JOIN YetAnotherTable yat            USING(field)
        ON (...)                         LEFT JOIN YetAnotherTable yat
WHERE                                        ON (...)
    payday = ?                       WHERE
    AND                                  payday BETWEEN ? AND ?
    (long_long_list_of_conditions)       AND
                                         (long_long_list_of_conditions)
                                     GROUP BY payday
Do on Perl side what DB can do
                                          X10 slower!
                                     SELECT
SELECT SUM(amount) AS result             payday,
FROM Table t                             SUM(amount) AS result
    LEFT JOIN AnotherTable at        FROM Table t
        USING(field)                     LEFT JOIN AnotherTable at
    LEFT JOIN YetAnotherTable yat            USING(field)
        ON (...)                         LEFT JOIN YetAnotherTable yat
WHERE                                        ON (...)
    payday = ?                       WHERE
    AND                                  payday BETWEEN ? AND ?
    (long_long_list_of_conditions)       AND
                                         (long_long_list_of_conditions)
                                     GROUP BY payday
I don't tell you
I don't tell you




“ Do NOT refactor! ”
I tell you




“ Do NOT refactor just because you can! ”
Think you!
Thank you!

More Related Content

Viewers also liked

B2B email list rental information - special offers
B2B email list rental information - special offersB2B email list rental information - special offers
B2B email list rental information - special offersAzam Marketing
 
The Affiliate Sales Kit - Writing Killer Proposals and Selling Yourself to Me...
The Affiliate Sales Kit - Writing Killer Proposals and Selling Yourself to Me...The Affiliate Sales Kit - Writing Killer Proposals and Selling Yourself to Me...
The Affiliate Sales Kit - Writing Killer Proposals and Selling Yourself to Me...Azam Marketing
 
Volgodonsk gorod-buduschego
Volgodonsk gorod-buduschegoVolgodonsk gorod-buduschego
Volgodonsk gorod-buduschegoOmsk State Univ
 
Создание национальной системы реабилитации наркозависимых
Создание национальной системы реабилитации наркозависимыхСоздание национальной системы реабилитации наркозависимых
Создание национальной системы реабилитации наркозависимыхOmsk State Univ
 

Viewers also liked (6)

B2B email list rental information - special offers
B2B email list rental information - special offersB2B email list rental information - special offers
B2B email list rental information - special offers
 
Perl Vs. Java
Perl Vs. JavaPerl Vs. Java
Perl Vs. Java
 
The Affiliate Sales Kit - Writing Killer Proposals and Selling Yourself to Me...
The Affiliate Sales Kit - Writing Killer Proposals and Selling Yourself to Me...The Affiliate Sales Kit - Writing Killer Proposals and Selling Yourself to Me...
The Affiliate Sales Kit - Writing Killer Proposals and Selling Yourself to Me...
 
Gdb 1-concept
Gdb 1-conceptGdb 1-concept
Gdb 1-concept
 
Volgodonsk gorod-buduschego
Volgodonsk gorod-buduschegoVolgodonsk gorod-buduschego
Volgodonsk gorod-buduschego
 
Создание национальной системы реабилитации наркозависимых
Создание национальной системы реабилитации наркозависимыхСоздание национальной системы реабилитации наркозависимых
Создание национальной системы реабилитации наркозависимых
 

Similar to About the dangers of refactoring

Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
R57php 1231677414471772-2
R57php 1231677414471772-2R57php 1231677414471772-2
R57php 1231677414471772-2ady36
 
Writing Maintainable Perl
Writing Maintainable PerlWriting Maintainable Perl
Writing Maintainable Perltinypigdotcom
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2osfameron
 
LAMP_TRAINING_SESSION_6
LAMP_TRAINING_SESSION_6LAMP_TRAINING_SESSION_6
LAMP_TRAINING_SESSION_6umapst
 
Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)osfameron
 
Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottO'Reilly Media
 
perl usage at database applications
perl usage at database applicationsperl usage at database applications
perl usage at database applicationsJoe Jiang
 
There's more than one way to empty it
There's more than one way to empty itThere's more than one way to empty it
There's more than one way to empty itAndrew Shitov
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongersbrian d foy
 
PERL for QA - Important Commands and applications
PERL for QA - Important Commands and applicationsPERL for QA - Important Commands and applications
PERL for QA - Important Commands and applicationsSunil Kumar Gunasekaran
 
Benchmarking Perl (Chicago UniForum 2006)
Benchmarking Perl (Chicago UniForum 2006)Benchmarking Perl (Chicago UniForum 2006)
Benchmarking Perl (Chicago UniForum 2006)brian d foy
 
[Erlang LT] Regexp Perl And Port
[Erlang LT] Regexp Perl And Port[Erlang LT] Regexp Perl And Port
[Erlang LT] Regexp Perl And PortKeiichi Daiba
 
Erlang with Regexp Perl And Port
Erlang with Regexp Perl And PortErlang with Regexp Perl And Port
Erlang with Regexp Perl And PortKeiichi Daiba
 

Similar to About the dangers of refactoring (20)

Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
R57php 1231677414471772-2
R57php 1231677414471772-2R57php 1231677414471772-2
R57php 1231677414471772-2
 
Nop2
Nop2Nop2
Nop2
 
Writing Maintainable Perl
Writing Maintainable PerlWriting Maintainable Perl
Writing Maintainable Perl
 
Php2
Php2Php2
Php2
 
Perl Presentation
Perl PresentationPerl Presentation
Perl Presentation
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
 
LAMP_TRAINING_SESSION_6
LAMP_TRAINING_SESSION_6LAMP_TRAINING_SESSION_6
LAMP_TRAINING_SESSION_6
 
Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)
 
Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter Scott
 
perl usage at database applications
perl usage at database applicationsperl usage at database applications
perl usage at database applications
 
There's more than one way to empty it
There's more than one way to empty itThere's more than one way to empty it
There's more than one way to empty it
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 
PERL for QA - Important Commands and applications
PERL for QA - Important Commands and applicationsPERL for QA - Important Commands and applications
PERL for QA - Important Commands and applications
 
Benchmarking Perl (Chicago UniForum 2006)
Benchmarking Perl (Chicago UniForum 2006)Benchmarking Perl (Chicago UniForum 2006)
Benchmarking Perl (Chicago UniForum 2006)
 
Method::Signatures
Method::SignaturesMethod::Signatures
Method::Signatures
 
[Erlang LT] Regexp Perl And Port
[Erlang LT] Regexp Perl And Port[Erlang LT] Regexp Perl And Port
[Erlang LT] Regexp Perl And Port
 
Erlang with Regexp Perl And Port
Erlang with Regexp Perl And PortErlang with Regexp Perl And Port
Erlang with Regexp Perl And Port
 

Recently uploaded

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 

Recently uploaded (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 

About the dangers of refactoring

  • 1. About the dangers of refactoring Andrei Pratasavitski May Perl + Perl Mova 2012-05-12
  • 2. Refactoring Code refactoring is a "disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior" [Martin Fowler in http://refactoring.com/], undertaken in order to improve some of the nonfunctional attributes of the software. Wikipedia
  • 3. Рефакторинг Рефакторинг или рефакторирование (англ. refactoring) — процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы. RU.Wikipedia
  • 4. Рефакторинг Рефакторинг (англ. refactoring) — перетворення програмного коду, зміна внутрішньої структури програмного забезпечення для полегшення розуміння коду і легшого внесення подальших змін без зміни зовнішньої поведінки самої системи. UA.Wikipedia
  • 5. Refactoring ● Restructuring an existing body of code ● Non-functional ● Without changing its external behavior
  • 6. THE AXIOM Developers DO love refactoring
  • 7. Refactoring ● Makes developers' lives easy and happy ● Brighter ● Creates an illusion of hardworking brains ● And...
  • 8. And refactoring... ● ...does NOTHING for users
  • 9. Refactoring What they want to do... What they do...
  • 10. Why is Refactoring a dirty word? ● Writing code is easier than reading it. ● So, “refactoring” often means “rewriting”. ● Understanding code requires reading it. ● How can you rewrite code that you don't understand? ● Probably not very well...
  • 11. You can't refactor the world... ● The world is often a messy place. ● If code deals with the real word it probably will be messy too. ● Refactoring can't make the world less complex or messy.
  • 12. Refactoring gone wrong ● People tend to delete what they don't understand in the misguided hope that “it was not used”. ● They do it too early, and too often. Its not like voting! ● They tend to over generalize and violate YAGNI.
  • 13. Refactoring has risks... ● You might... break something ● ... refactor the code in such a way that the maintainer doesn't understand. ● ... annoy your colleagues ● … refactor something for the wrong priority ● … make the code harder to maintain ● … waste time by treading water
  • 14. (Thanks to Yves Orton) Developer Craft (December 2011)
  • 15. This is what business says
  • 16. This is what business says Because ...and business developers wants want results... beauty!
  • 17. This is what business says ...and developers want beauty!
  • 18. This is what business says
  • 23. Code WTF WTF ● Watch
  • 24. Code WTF WTF ● Watch ● Think
  • 25. Code WTF WTF ● Watch ● Think ● Figure out
  • 26. Code WTF WTF ● Watch ● Think ● Figure out Philippe (BooK) Bruhat
  • 28. Code evil is... ● ...map in void context ● ...goto ● ...repeating code ● ...using properties instead of accessors ● ...to not use foreign keys ● ...to do on Perl side what DB can do
  • 29. Code evil is... ● ...map in void context ● ...goto ● ...repeating code ● ...using properties instead of accessors ● ...to not use foreign keys ● ...to do on Perl side what DB can do Why?
  • 30. Because... ● ...it looks ugly! ● ...it is hard to read! ● ...it is a bad practice! ● ...it will bring benefits in the future! ● ...there is another way to do it! ● ...it sucks! ● ...I don't like it!
  • 31. But how about... ...performance?
  • 32. map in void context
  • 33. map in void context use Benchmark qw(cmpthese); my @arr; my $times = 1_000_000; sub ss { $_[0] =~ s/1/a/; } cmpthese( $times, { map1 => sub { @arr = 1..100; map s/1/a/, @arr; }, map2 => sub { @arr = 1..100; map { s/1/a/ } @arr; }, map3 => sub { @arr = 1..100; map &ss($_), @arr; }, map4 => sub { @arr = 1..100; map { &ss($_) } @arr; }, for1 => sub { @arr = 1..100; for (@arr) { s/1/a/ }; }, for2 => sub { @arr = 1..100; s/1/a/ for @arr; }, for3 => sub { @arr = 1..100; do { s/1/a/ } for @arr; }, for4 => sub { @arr = 1..100; for (@arr) { &ss($_) }; }, for5 => sub { @arr = 1..100; &ss($_) for @arr; }, for6 => sub { @arr = 1..100; do { &ss($_) } for @arr; }, for7 => sub { @arr = 1..100; do &ss($_) for @arr; }, } );
  • 34. map in void context use Benchmark qw(cmpthese); my @arr; my $times = 1_000_000; sub ss { $_[0] =~ s/1/a/; } cmpthese( $times, { map1 => sub { @arr = 1..100; map s/1/a/, @arr; }, map2 => sub { @arr = 1..100; map { s/1/a/ } @arr; }, map3 => sub { @arr = 1..100; map &ss($_), @arr; }, map4 => sub { @arr = 1..100; map { &ss($_) } @arr; }, for1 => sub { @arr = 1..100; for (@arr) { s/1/a/ }; }, for2 => sub { @arr = 1..100; s/1/a/ for @arr; }, for3 => sub { @arr = 1..100; do { s/1/a/ } for @arr; }, for4 => sub { @arr = 1..100; for (@arr) { &ss($_) }; }, for5 => sub { @arr = 1..100; &ss($_) for @arr; }, for6 => sub { @arr = 1..100; do { &ss($_) } for @arr; }, for7 => sub { @arr = 1..100; do &ss($_) for @arr; }, } );
  • 35. map in void context use Benchmark qw(cmpthese); my @arr; my $times = 1_000_000; sub ss { $_[0] =~ s/1/a/; } cmpthese( $times, { map1 => sub { @arr = 1..100; map s/1/a/, @arr; }, map2 => sub { @arr = 1..100; map { s/1/a/ } @arr; }, map3 => sub { @arr = 1..100; map &ss($_), @arr; }, map4 => sub { @arr = 1..100; map { &ss($_) } @arr; }, for1 => sub { @arr = 1..100; for (@arr) { s/1/a/ }; }, for2 => sub { @arr = 1..100; s/1/a/ for @arr; }, for3 => sub { @arr = 1..100; do { s/1/a/ } for @arr; }, for4 => sub { @arr = 1..100; for (@arr) { &ss($_) }; }, for5 => sub { @arr = 1..100; &ss($_) for @arr; }, for6 => sub { @arr = 1..100; do { &ss($_) } for @arr; }, for7 => sub { @arr = 1..100; do &ss($_) for @arr; }, } );
  • 36. map in void context use Benchmark qw(cmpthese); my @arr; my $times = 1_000_000; sub ss { $_[0] =~ s/1/a/; } cmpthese( $times, { map1 => sub { @arr = 1..100; map s/1/a/, @arr; }, map2 => sub { @arr = 1..100; map { s/1/a/ } @arr; }, map3 => sub { @arr = 1..100; map &ss($_), @arr; }, map4 => sub { @arr = 1..100; map { &ss($_) } @arr; }, for1 => sub { @arr = 1..100; for (@arr) { s/1/a/ }; }, for2 => sub { @arr = 1..100; s/1/a/ for @arr; }, for3 => sub { @arr = 1..100; do { s/1/a/ } for @arr; }, for4 => sub { @arr = 1..100; for (@arr) { &ss($_) }; }, for5 => sub { @arr = 1..100; &ss($_) for @arr; }, for6 => sub { @arr = 1..100; do { &ss($_) } for @arr; }, for7 => sub { @arr = 1..100; do &ss($_) for @arr; }, } );
  • 37. Results for7 map4 map3 for6 map2 for4 for5 for3 for1 for2 map1 for7 -- -91% -91% -93% -93% -94% -94% -95% -95% -96% -96% map4 963% -- -5% -26% -29% -32% -33% -45% -52% -52% -53% map3 1022% 6% -- -22% -25% -28% -29% -42% -49% -50% -51% for6 1338% 35% 28% -- -4% -8% -9% -26% -35% -36% -37% map2 1396% 41% 33% 4% -- -4% -5% -23% -32% -33% -34% for4 1461% 47% 39% 9% 4% -- -1% -20% -29% -30% -32% for5 1476% 48% 40% 10% 5% 1% -- -19% -29% -30% -31% for3 1844% 83% 73% 35% 30% 25% 23% -- -12% -13% -15% for1 2110% 108% 97% 54% 48% 42% 40% 14% -- -1% -3% for2 2137% 110% 99% 56% 49% 43% 42% 15% 1% -- -2% map1 2181% 115% 103% 59% 52% 46% 45% 17% 3% 2% --
  • 38. Results for7 map4 map3 for6 map2 for4 for5 for3 for1 for2 map1 for7 -- -91% -91% -93% -93% -94% -94% -95% -95% -96% -96% map4 963% -- -5% -26% -29% -32% -33% -45% -52% -52% -53% map3 1022% 6% -- -22% -25% -28% -29% -42% -49% -50% -51% for6 1338% 35% 28% -- -4% -8% -9% -26% -35% -36% -37% map2 1396% 41% 33% 4% -- -4% -5% -23% -32% -33% -34% for4 1461% 47% 39% 9% 4% -- -1% -20% -29% -30% -32% for5 1476% 48% 40% 10% 5% 1% -- -19% -29% -30% -31% for3 1844% 83% 73% 35% 30% 25% 23% -- -12% -13% -15% for1 2110% 108% 97% 54% 48% 42% 40% 14% -- -1% -3% for2 2137% 110% 99% 56% 49% 43% 42% 15% 1% -- -2% map1 2181% 115% 103% 59% 52% 46% 45% 17% 3% 2% --
  • 39. Results cmpthese( $times, { for1 => sub { @arr = 1..100; for (@arr) { s/1/a/ }; }, for2 => sub { @arr = 1..100; s/1/a/ for @arr; }, map1 => sub { @arr = 1..100; map s/1/a/, @arr; }, } ); for1 for2 map1 for1 -- -1% -4% for2 1% -- -3% map1 4% 3% --
  • 40. Results cmpthese( $times, { for1 => sub { @arr = 1..100; for (@arr) { s/1/a/ }; }, for2 => sub { @arr = 1..100; s/1/a/ for @arr; }, map1 => sub { @arr = 1..100; map s/1/a/, @arr; }, } ); for1 for2 map1 for1 -- -1% -4% for2 1% -- -3% map1 4% 3% --
  • 41. map in void context ...is faster
  • 42. map in void context ...is faster ...a bit
  • 43. map in void context ...is faster ...a bit ...sometimes
  • 44. map in void context 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 45. Have a look at... 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 46. Have a look at... 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 47. Have a look at... 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 48. Have a look at... 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 49. Have a look at... 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 50. Have a look at... 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 51. Have a look at... 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 52. Have a look at... 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 54. Repeating code my ($row, @rows) my $tmp = $sth->fetchrow_hashref(); while ( $row = $sth->fetchrow_hashref() ) { if ( $row->{field} eq $tmp->{field} ) { push @rows, $row; } else { # do something with $tmp and @rows $tmp = $row; } }
  • 55. Repeating code my ($row, @rows) my $tmp = $sth->fetchrow_hashref(); while ( $row = $sth->fetchrow_hashref() ) { if ( $row->{field} eq $tmp->{field} ) { push @rows, $row; } else { # do something with $tmp and @rows $tmp = $row; } } # do something with $tmp and @rows
  • 56. Repeating code my ($row, @rows) my $tmp = $sth->fetchrow_hashref(); while ( $row = $sth->fetchrow_hashref() ) { if ( $row->{field} eq $tmp->{field} ) { push @rows, $row; } else { &do_something($tmp, @rows); $tmp = $row; } } &do_something($tmp, @rows);
  • 57. Repeating code 1. map1 | 2181% | map s/1/a/, @arr; 2. for2 | 2137% | s/1/a/ for @arr; 3. for1 | 2110% | for (@arr) { s/1/a/ }; 4. for3 | 1844% | do { s/1/a/ } for @arr; 5. for5 | 1476% | &ss($_) for @arr; 6. for4 | 1461% | for (@arr) { &ss($_) }; 7. map2 | 1396% | map { s/1/a/ } @arr; 8. for6 | 1338% | do { &ss($_) } for @arr; 9. map3 | 1022% | map &ss($_), @arr; 10. map4 | 963% | map { &ss($_) } @arr; 11. for7 | 0% | do &ss($_) for @arr;
  • 58. Repeating code ...can be useful
  • 59. Repeating code ...can be useful ...if you remember that method/function call is expensive
  • 61. Properties instead of accessors $request->stash(key => 'value');
  • 62. Properties instead of accessors my $stash = $request->stash(); $stash->{key} = 'value';
  • 63. Properties instead of accessors my $stash = $request->{stash}; $stash->{key} = 'value';
  • 65. goto is evil? Really?
  • 66. goto is evil? $ ack-grep -a '^s*gotos+' /usr/lib/perl/5.14/*.pm | wc -l 10 $ ack-grep -a '^s*gotos+' /usr/share/perl/5.14/*.pm | wc -l 29
  • 67. goto is evil? All those cases have goto &somewhere; in AUTOLOAD
  • 69. goto is evil? Yes, it's evil!
  • 70. Do on Perl side what DB can do
  • 71. Do on Perl side what DB can do my @days = &days_from_period('2010-08-01', '2010-08-31'); # here @days = ('2010-08-01', '2010-08-01', '2010-08-01', ... '2010-08-31') my %result = (); my $sth = $dbh->prepare(<<'SQL'); SELECT SUM(amount) AS result FROM Table t LEFT JOIN AnotherTable at USING(field) LEFT JOIN YetAnotherTable yat ON (...) WHERE payday = ? AND (long_long_list_of_conditions) SQL for my $day (@days) { $sth->execute($day); $result{day} = $stf->fetchrow_arrayref()->[0] || 0; }
  • 72. # my @days = &days_from_period('2010-08-01', '2010-08-31'); # here @days = ('2010-08-01', '2010-08-01', '2010-08-01', ... '2010-08-31') my %result = (); # my $sth = $dbh->prepare(<<'SQL'); my $sql = <<'SQL'; SELECT payday, SUM(amount) AS result FROM Table t LEFT JOIN AnotherTable at USING(field) LEFT JOIN YetAnotherTable yat ON (...) WHERE payday BETWEEN ? AND ? AND (long_long_list_of_conditions) GROUP BY payday SQL # for my $day (@days) { # $sth->execute($day); # $result{day} = $stf->fetchrow_arrayref()->[0] || 0; %result = $sth->selectall_hashref($sql, 'payday', undef, '2010-08-01', '2010-08-31'); # }
  • 73. my %result = (); my $sql = <<'SQL'; SELECT payday, SUM(amount) AS result FROM Table t LEFT JOIN AnotherTable at USING(field) LEFT JOIN YetAnotherTable yat ON (...) WHERE payday BETWEEN ? AND ? AND (long_long_list_of_conditions) GROUP BY payday SQL %result = $sth->selectall_hashref($sql, 'payday', undef, '2010-08-01', '2010-08-31');
  • 74. Do on Perl side what DB can do
  • 75. Do on Perl side what DB can do SELECT SELECT SUM(amount) AS result payday, FROM Table t SUM(amount) AS result LEFT JOIN AnotherTable at FROM Table t USING(field) LEFT JOIN AnotherTable at LEFT JOIN YetAnotherTable yat USING(field) ON (...) LEFT JOIN YetAnotherTable yat WHERE ON (...) payday = ? WHERE AND payday BETWEEN ? AND ? (long_long_list_of_conditions) AND (long_long_list_of_conditions) GROUP BY payday
  • 76. Do on Perl side what DB can do X10 slower! SELECT SELECT SUM(amount) AS result payday, FROM Table t SUM(amount) AS result LEFT JOIN AnotherTable at FROM Table t USING(field) LEFT JOIN AnotherTable at LEFT JOIN YetAnotherTable yat USING(field) ON (...) LEFT JOIN YetAnotherTable yat WHERE ON (...) payday = ? WHERE AND payday BETWEEN ? AND ? (long_long_list_of_conditions) AND (long_long_list_of_conditions) GROUP BY payday
  • 78. I don't tell you “ Do NOT refactor! ”
  • 79. I tell you “ Do NOT refactor just because you can! ”