We got nominated! Help us out and vote for GitHub as Best Bootstrapped Startup of 2008. (You can vote once a day.) [ hide ]

public
Description: Phusion Passenger (mod_rails)
Homepage: http://www.modrails.com/
Clone URL: git://github.com/FooBarWidget/passenger.git
Click here to lend your support to: passenger and make a donation at www.pledgie.com !
passenger / benchmark / accept_vs_socketpair_vs_named_pipes.rb
100755 127 lines (119 sloc) 2.644 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env ruby
require 'benchmark'
require 'socket'
require 'dl/import'
 
ITERATIONS = 100000
# Constants to relieve the garbage collector
MESSAGE = " " * 512
MESSAGE_SIZE = [MESSAGE.size].pack('n')
FIFO = 'fifo'
R = 'r'
W = 'w'
 
def start
  if ARGV.empty?
    benchmark_accept
    benchmark_socketpair
    benchmark_named_pipes
  elsif ARGV.size == 1 && ARGV[0] == 'accept'
    benchmark_accept
  elsif ARGV.size == 1 && ARGV[0] == 'socketpair'
    benchmark_socketpair
  elsif ARGV.size == 1 && ARGV[0] == 'named_pipes'
    benchmark_named_pipes
  else
    puts "Usage: accept_vs_socketpair.rb <accept|socketpair>"
    exit(1)
  end
end
 
def benchmark_accept
  begin
    puts "Benchmarking accept()..."
    File.unlink("benchmark.socket") rescue nil
    pid = fork do
      server = UNIXServer.new("benchmark.socket")
      ITERATIONS.times do
        client = server.accept
        client.readline
        client.close
      end
      server.close
    end
    result = Benchmark.measure do
      ITERATIONS.times do
        conn = UNIXSocket.new("benchmark.socket")
        conn.puts("hello")
        conn.close
      end
    end
    Process.waitpid(pid)
    puts "User/system/real time: #{result}"
    printf "%.2f messages per second\n", ITERATIONS / result.real
  ensure
    File.unlink("benchmark.socket") rescue nil
  end
end
 
def benchmark_socketpair
  puts "Benchmarking socketpair()..."
  listener, connector = UNIXSocket.pair
  pid = fork do
    connector.close
    ITERATIONS.times do
      a, b = UNIXSocket.pair
      listener.send_io(a)
      a.close
      b.readline
      b.close
    end
    listener.close
  end
  result = Benchmark.measure do
    listener.close
    ITERATIONS.times do
      conn = connector.recv_io
      conn.puts("hello")
      conn.close
    end
    connector.close
  end
  Process.waitpid(pid)
  puts "User/system/real time: #{result}"
  printf "%.2f messages per second\n", ITERATIONS / result.real
end
 
def benchmark_named_pipes
  puts "Benchmarking named pipes..."
  listener, connector = UNIXSocket.pair
  pid = fork do
    connector.close
    ITERATIONS.times do
      LIBC.mkfifo(FIFO, 0600)
      listener.write("#{FIFO}\n")
      File.open(FIFO, R) do |f|
        f.readline
      end
      File.unlink(FIFO)
    end
    listener.close
  end
  result = Benchmark.measure do
    listener.close
    ITERATIONS.times do
      fifo_name = connector.readline
      fifo_name.rstrip!
      File.open(fifo_name, W) do |f|
        f.puts("hello")
      end
    end
    connector.close
  end
  Process.waitpid(pid)
  puts "User/system/real time: #{result}"
  printf "%.2f messages per second\n", ITERATIONS / result.real
end
 
# Urgh, Ruby does not support mkfifo...
module LIBC
  extend DL::Importable
  dlload 'libc.so.6'
  extern 'int mkfifo(char*, uint)'
  extern 'void perror(char*)'
end
 
start