Skip to content

Instantly share code, notes, and snippets.

@kazeburo
Last active December 26, 2015 04:29
Show Gist options
  • Save kazeburo/7093522 to your computer and use it in GitHub Desktop.
Save kazeburo/7093522 to your computer and use it in GitHub Desktop.
diff --git a/lib/Plack/Response.pm b/lib/Plack/Response.pm
index 5ea2e15..aba8364 100644
--- a/lib/Plack/Response.pm
+++ b/lib/Plack/Response.pm
@@ -85,24 +85,20 @@ sub finalize {
my $self = shift;
Carp::croak "missing status" unless $self->status();
- my $headers = $self->headers->clone;
- $self->_finalize_cookies($headers);
+ my $headers = $self->headers;
+ my @headers;
+ $headers->scan(sub{
+ my ($k,$v) = @_;
+ $v =~ s/\015\012[\040|\011]+/chr(32)/ge; # replace LWS with a single SP
+ $v =~ s/\015|\012//g; # remove CR and LF since the char is invalid here
+ push @headers, $k, $v;
+ });
+
+ $self->_finalize_cookies(\@headers);
return [
$self->status,
- +[
- map {
- my $k = $_;
- map {
- my $v = $_;
- $v =~ s/\015\012[\040|\011]+/chr(32)/ge; # replace LWS with a single SP
- $v =~ s/\015|\012//g; # remove CR and LF since the char is invalid here
-
- ( $k => $v )
- } $headers->header($_);
-
- } $headers->header_field_names
- ],
+ \@headers,
$self->_body,
];
}
@@ -129,7 +125,7 @@ sub _finalize_cookies {
while (my($name, $val) = each %{$self->cookies}) {
my $cookie = $self->_bake_cookie($name, $val);
- $headers->push_header('Set-Cookie' => $cookie);
+ push @$headers, 'Set-Cookie' => $cookie;
}
}

patched

% perl -Ilib bench.pl 
Benchmark: running bench_hello for at least 3 CPU seconds...
bench_hello:  3 wallclock secs ( 3.22 usr +  0.00 sys =  3.22 CPU) @ 39442.24/s (n=127004)
               Rate bench_hello
bench_hello 39442/s    

original

% perl bench.pl  
Benchmark: running bench_hello for at least 3 CPU seconds...
bench_hello:  3 wallclock secs ( 3.16 usr +  0.00 sys =  3.16 CPU) @ 20510.44/s (n=64813)
               Rate bench_hello
bench_hello 20510/s          --
use HTTP::Request::Common;
use HTTP::Message::PSGI;
use Plack::Response;
use Benchmark qw/cmpthese timethese/;
my $env = req_to_psgi(GET "/");
my $app = sub {
my $res = Plack::Response->new(200);
$res->content_type('text/plain');
$res->content_length(12);
$res->body("Hello World\n");
$res->finalize;
};
cmpthese(timethese(0,{
'bench_hello' => sub {
$app->($env);
}
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment