Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #8 from timbunce/tim-perf1

This branch is 13 times faster than the 0.07 release :)
  • Loading branch information...
commit 21e56f3e1bc0e0deb4ba20e13dbbcabde69190b9 2 parents 5f31695 + 85b6984
@cosimo authored
View
35 benchmark.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+=head1 NAME
+
+benchmark.pl - report max send rate
+
+=head1 DESCRIPTION
+
+A basic test of the time is takes to send stats.
+
+=cut
+
+use strict;
+use warnings;
+
+use Net::Statsd;
+use Benchmark;
+use Getopt::Long;
+
+GetOptions(
+ 'host|h=s' => \($Net::Statsd::HOST = 'localhost'),
+ 'port|p=i' => \($Net::Statsd::PORT = 9), # port 9 is the standard discard service
+) or exit 1;
+
+my $count = shift || 10_000;
+
+print "Using $INC{'Net/Statsd.pm'} sending to $Net::Statsd::HOST:$Net::Statsd::PORT\n";
+
+timethese($count, {
+ increment => sub { Net::Statsd::increment('foo.bar.i') },
+ decrement => sub { Net::Statsd::increment('foo.bar.d') },
+ timing_100 => sub { Net::Statsd::timing('foo.bar.t', 1) },
+ timing_001 => sub { Net::Statsd::timing('foo.bar.t', 0.1) },
+ gauge => sub { Net::Statsd::gauge('foo.bar.g', 42) },
+});
View
56 lib/Net/Statsd.pm
@@ -11,6 +11,9 @@ use IO::Socket ();
our $HOST = 'localhost';
our $PORT = 8125;
+my $SOCK;
+my $SOCK_PEER;
+
=head1 NAME
Net::Statsd - Perl client for Etsy's statsd daemon
@@ -242,31 +245,42 @@ sub send {
return;
}
- my $udp_sock = IO::Socket::INET->new(
- Proto => 'udp',
- PeerAddr => $HOST,
- PeerPort => $PORT,
- ) or do {
- # warn perhaps?
- return
- };
-
- # We don't want to die if Net::Statsd::send() doesn't work...
- # We could though:
- #
- # or die "Could not create UDP socket: $!\n";
+ # cache the socket to avoid dns and socket creation overheads
+ # (this boosts performance from ~6k to >60k sends/sec)
+ if (!$SOCK || !$SOCK_PEER || "$HOST:$PORT" ne $SOCK_PEER) {
+
+ $SOCK = IO::Socket::INET->new(
+ Proto => 'udp',
+ PeerAddr => $HOST,
+ PeerPort => $PORT,
+ ) or do {
+ Carp::carp("Net::Statsd can't create a socket to $HOST:$PORT: $!")
+ unless our $_warn_once->{"$HOST:$PORT"}++;
+ return
+ };
+ $SOCK_PEER = "$HOST:$PORT";
+
+ # We don't want to die if Net::Statsd::send() doesn't work...
+ # We could though:
+ #
+ # or die "Could not create UDP socket: $!\n";
+ }
my $all_sent = 1;
- for my $stat (keys %{ $sampled_data }) {
- my $value = $sampled_data->{$stat};
+ keys %{ $sampled_data }; # reset iterator
+ while ( my ($stat, $value) = each %{ $sampled_data } ) {
my $packet = "$stat:$value";
- $udp_sock->send($packet);
- # XXX If you want warnings...
- # or do {
- # warn "[" . localtime() . "] UDP packet '$packet' send failed\n";
- # $all_sent = 0;
- #};
+ # send() returns the number of characters sent, or undef on error.
+ my $r = send($SOCK, $packet, 0);
+ if (!defined $r) {
+ #warn "Net::Statsd send error: $!";
+ $all_sent = 0;
+ }
+ elsif ($r != length($packet)) {
+ #warn "Net::Statsd send truncated: $!";
+ $all_sent = 0;
+ }
}
return $all_sent;
View
3  t/MockServer.pm
@@ -56,13 +56,11 @@ sub run {
# Timer
if ($fields[1] eq 'ms') {
- $msg->{timers} = [] unless $msg->{timers};
push @{$msg->{timers}}, $fields[0];
}
# Gauge (FIXME I'll just pretend this is correct)
elsif ($fields[1] eq 'g') {
- $msg->{gauges} = [] unless $msg->{gauges};
push @{$msg->{gauges}}, $fields[0];
}
@@ -71,7 +69,6 @@ sub run {
if ($fields[2] && $fields[2] =~ /^\s*@([\d\.]+)/) {
$msg->{sample_rate} = $1;
}
- $msg->{counters} = [] unless $msg->{counters};
push @{$msg->{counters}}, $fields[0];
}
}
View
2  t/mock-server.t
@@ -113,7 +113,7 @@ for (1 .. $tries) {
my $expected_seen = $tries * $sample_rate;
my $num_seen = scalar @messages;
-diag("Got $num_seen samples out of $tries tries");
+diag("Got $num_seen samples out of $tries tries (sample rate $sample_rate)");
cmp_ok(
int(abs($num_seen - $expected_seen)), '<=', (int($expected_seen * 0.05) | 1),
"5% delta or less"
Please sign in to comment.
Something went wrong with that request. Please try again.