First step of Performance Tuning

59
by risou at YAPC::Kansai 2017 Osaka

Transcript of First step of Performance Tuning

by risou at YAPC::Kansai 2017 Osaka

▸ risou

▸ ID "risouf"

▸ 🤔

▸ 🙏

▸ Web

▸ 10

▸ 10 ……

▸ 10 5

A 3h

B 1h

C 0.5h

D 1h

E 2h

F 1h

G 4h

H 2h

A 3h

B 1h

C 0.5h

D 1h

E 2h

F 1h

G 4h

H 2h

▸ Web

▸ 1

my @primes = ();for my $num (2 .. 100_000) { if ($num == 2) { push @primes, $num; next; }

my $is_prime = 1; for (2 .. $num - 1) { if ($num % $_ == 0) { $is_prime = 0; } } if ($is_prime == 1) { push @primes, $num; }}

▸ 366.103 sec

▸ oh...

▸ 10 6

▸ 10

▸ 50

1 2 - 1

my @primes = ();for my $num (2 .. 100_000) { if ($num == 2) { push @primes, $num; next; }

my $is_prime = 1; for (2 .. $num - 1) { if ($num % $_ == 0) { $is_prime = 0; last; } } if ($is_prime == 1) { push @primes, $num; }}

▸ 31.404 sec

▸ 1/10

▸ 5

▸ 2

25

▸my @primes = ();for my $num (2 .. 100_000) { if ($num == 2) { push @primes, $num; next; }

my $is_prime = 1; for (@primes) { if ($num % $_ == 0) { $is_prime = 0; last; } } if ($is_prime == 1) { push @primes, $num; }}

▸ 4 = 2 x 2 60 = 2 x 2 x 3 x 5

▸ 4 2

60 2 3 5

▸ @primes

@primes

▸ 3.191 sec

▸ 1/10

▸ ……

▸ 91 7 13

▸ 91 13

▸ 91 13

▸ N

√N

▸ 91 9.53...

▸ 2 9 10 90

▸ √N my @primes = ();for my $num (2 .. 100_000) { if ($num == 2) { push @primes, $num; next; }

my $is_prime = 1; for (@primes) { last if $_ > sqrt($num); if ($num % $_ == 0) { $is_prime = 0; last; } } if ($is_prime == 1) { push @primes, $num; }}

▸ 0.126 sec

▸ 1

▸ 1/3000

……

▸my @primes = ();for my $num (2 .. 100_000) { if ($num == 2) { push @primes, $num; next; }

my $is_prime = 1; for (@primes) { last if $_ > sqrt($num); if ($num % $_ == 0) { $is_prime = 0; last; } } if ($is_prime == 1) { push @primes, $num; }}

▸ 2

▸ 2

▸ 2

my @numbers = (1) x 100_001;$numbers[0] = 0;$numbers[1] = 0;for my $num (2 .. sqrt(100_000)) { if ($numbers[$num]) { for (2 .. (100_000 / $num)) { $numbers[$num * $_] = 0; } }}

▸ 0.026 sec

▸ ……

▸ memoization ( not memonization )

# normalsub fib { my $number = shift; return 1 if $number == 1 || $number == 2; return fib($number - 1) + fib($number - 2);}

# memoizemy %memo;sub fib { my $number = shift; return 1 if $number == 1 || $number == 2; return $memo{$number} if $memo{$number}; $memo{$number} = fib($number - 1) + fib($number - 2); return $memo{$number};}

▸ 30

▸ normal: 545.545 msec / memoize: 0.114 msec

▸ is_prime

▸ is_prime

▸ Perl

▸ Memoise

▸ normal memoize('fib');

▸ Memoise 30 18.654 msec

▸ Memoise

List::Compare

▸ 2

List::Compare

▸ 10

▸ List::Compare get_Lonly

List::Compare

▸ List::Compare

# List::Comparemy $lc = List::Compare->new(\@primes, \@fibs);my @left_only = $lc->get_Lonly;

# normalmy %exists;%exists = map { $_ => 1 } @primes;for (@fibs) { $exists{$_} = 0 if ($exists{$_});}my @left_only = grep { $exists{$_} == 1 } keys %exists;

List::Compare

▸ List::Compare: 35.733 msec / normal: 17.769 msec

▸ List::Compare

1 List::Compare

▸ List::Compare new

▸ 1

▸ push join

# push -> joinmy @str;for (1 .. 1_000_000) { push @str, "The quick brown fox jumps over the lazy dog.";}my $result = join "", @str;

# concatmy $result;for (1 .. 1_000_000) { $result .= "The quick brown fox jumps over the lazy dog.";}

# multiple 2, 4 timesmy @numbers;for (1 .. 100_000_000) { push @numbers, $_ * 2 * 2 * 2 * 2;}

# multiple 16, 1 timemy @numbers;for (1 .. 100_000_000) { push @numbers, $_ * 16;}

# function in loopsub sum { my ($x, $y) = @_; return $x + $y;}

my $total = 0;for (1 .. 1_000_000) { $total = sum($total, $_);}

# loop in functionsub sum_list { my ($list) = @_; my $result; for (@$list) { $result += $_; } return $result;}

my $total = sum_list([1 .. 1_000_000]);

▸ Function in Loop: 360.701 msec

▸ Loop in Function: 94.884 msec

Function in Loop

Struct of Arrays

▸ Perl

▸ Struct of Arrays (SoA) Array of Structs (AoS)

▸ AoS

SoA

Struct of Arrays

▸ SoA AoS Clone # Array of Structsmy $aos = [];for (1 .. 100_000) { push @$aos, { number => $_, double => $_ * 2 };}my $copy = clone($aos);

# Struct of Arraysmy $soa = {};my @numbers;my @doubles;my $count;for (1 .. 100_000) { push @numbers, $_; push @doubles, $_ * 2;}$soa = { number => \@numbers, double => \@doubles };my $copy = clone($soa);

Struct of Arrays

▸ AoS: 640.302 msec / SoA: 215.323 msec

▸ SoA Clone

▸ AoS: 24,800,144 bytes / SoA: 6,400,424 bytes

▸ ……

▸ DB ……

▸ NYTProf

▸ DB

▸ DB/KVS

▸ CDN

▸ DB

▸ DB