Last active
December 12, 2015 02:28
-
-
Save therealadam/4698972 to your computer and use it in GitHub Desktop.
I took producer.rb, added threads and made it two orders of magnitude slower. Thus was born, lol.rb. (NOW LOLFAST)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'thread' | |
require 'ffaker' | |
require 'json' | |
def new_message | |
text = Faker::HipsterIpsum.sentences(3) | |
metrics = { | |
temp: rand(110), # degrees F | |
mass: rand(100), # kilograms | |
speed: rand(70) # miles per hour | |
} | |
{metrics: metrics, body: text} | |
end | |
def send_message(socket, msg) | |
encoded = JSON.dump(messages: msg) | |
socket.write(encoded) | |
end | |
FRAME_SIZE = 100 | |
if __FILE__ == $0 | |
# s = Socket.new('localhost', 4242) | |
s = $stdout | |
messages = Queue.new | |
producer = Thread.new do | |
loop do | |
messages.push(new_message) | |
end | |
end | |
begin | |
loop do | |
frame = FRAME_SIZE.times.map { messages.pop } | |
send_message(s, frame) | |
end | |
ensure | |
s.close | |
producer.join | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Using local file /Users/adam/.rbenv/versions/1.9.3-p327-perf/bin/ruby. | |
Using local file /tmp/profile. | |
Total: 1837 samples | |
754 41.0% 41.0% 1340 72.9% Enumerable#sort_by | |
317 17.3% 58.3% 1507 82.0% Range#each | |
299 16.3% 74.6% 299 16.3% garbage_collector | |
199 10.8% 85.4% 199 10.8% Float#<=> | |
81 4.4% 89.8% 81 4.4% Kernel.rand | |
34 1.9% 91.7% 71 3.9% Array#map | |
31 1.7% 93.4% 1496 81.4% Faker::Lorem#sentence | |
15 0.8% 94.2% 1433 78.0% Module#random_pick | |
15 0.8% 95.0% 15 0.8% String#initialize_copy | |
14 0.8% 95.8% 23 1.3% Kernel#rand | |
13 0.7% 96.5% 36 2.0% Kernel#dup | |
13 0.7% 97.2% 13 0.7% String#capitalize! | |
8 0.4% 97.6% 19 1.0% Kernel#initialize_dup | |
6 0.3% 97.9% 14 0.8% Array#join | |
6 0.3% 98.3% 6 0.3% File.file? | |
5 0.3% 98.5% 1524 83.0% Object#new_message | |
4 0.2% 98.7% 4 0.2% Array#[] | |
4 0.2% 99.0% 1430 77.8% Faker::HipsterIpsum#words | |
4 0.2% 99.2% 1504 81.9% Faker::Lorem#sentences | |
\342\230\201 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: UTF-8 | |
require 'socket' | |
require 'ffaker' | |
require 'json' | |
ZERO_LENGTH = 1024 * 8 | |
def new_message | |
text = Faker::HipsterIpsum.sentences(3) | |
random = File.read('/dev/zero', ZERO_LENGTH) | |
metrics = { | |
temp: rand(110), # degrees F | |
mass: rand(100), # kilograms | |
speed: rand(70) # miles per hour | |
} | |
{metrics: metrics, random: random, body: text} | |
end | |
def send_message(socket, msg) | |
encoded = JSON.dump(messages: msg) | |
socket.write(encoded) | |
end | |
FRAME_SIZE = 100 | |
if __FILE__ == $0 | |
s = TCPSocket.new('localhost', 4242) | |
# s = $stdout | |
begin | |
loop do | |
frame = FRAME_SIZE.times.map { new_message } | |
send_message(s, frame) | |
end | |
ensure | |
s.close | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'ffaker' | |
require 'json' | |
def new_message | |
text = Faker::HipsterIpsum.sentences(3) | |
metrics = { | |
temp: rand(110), # degrees F | |
mass: rand(100), # kilograms | |
speed: rand(70) # miles per hour | |
} | |
{metrics: metrics, body: text} | |
end | |
def send_message(socket, msg) | |
encoded = JSON.dump(messages: msg) | |
socket.write(encoded) | |
end | |
FRAME_SIZE = 100 | |
if __FILE__ == $0 | |
# s = Socket.new('localhost', 4242) | |
s = $stdout | |
begin | |
loop do | |
frame = FRAME_SIZE.times.map { new_message } | |
send_message(s, frame) | |
end | |
ensure | |
s.close | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Using local file /Users/adam/.rbenv/versions/1.9.3-p327-perf/bin/ruby. | |
Using local file /tmp/profile. | |
Total: 947 samples | |
370 39.1% 39.1% 725 76.6% Enumerable#sort_by | |
195 20.6% 59.7% 818 86.4% Range#each | |
118 12.5% 72.1% 118 12.5% Float#<=> | |
64 6.8% 78.9% 64 6.8% garbage_collector | |
43 4.5% 83.4% 43 4.5% Kernel.rand | |
23 2.4% 85.9% 23 2.4% IO#write | |
13 1.4% 87.2% 13 1.4% Array#join | |
12 1.3% 88.5% 26 2.7% Kernel#dup | |
11 1.2% 89.7% 37 3.9% Array#map | |
11 1.2% 90.8% 816 86.2% Faker::Lorem#sentence | |
10 1.1% 91.9% 10 1.1% String#initialize_copy | |
9 1.0% 92.8% 10 1.1% Kernel#rand | |
7 0.7% 93.6% 15 1.6% JSON::Ext::Generator::State#generate | |
6 0.6% 94.2% 10 1.1% Kernel#eval | |
6 0.6% 94.8% 774 81.7% Module#random_pick | |
6 0.6% 95.5% 829 87.5% Object#new_message | |
6 0.6% 96.1% 6 0.6% String#capitalize! | |
5 0.5% 96.6% 779 82.3% Faker::ArrayUtils#random_pick | |
4 0.4% 97.0% 4 0.4% Range.allocate | |
\342\230\201 |
@JEG2 check out lolput.rb. I cheated and got a lot closer to my baseline benchmark. On my laptop, this produces does about 75-78 MB/s of throughput:
# Producer
$ cat /dev/zero | nc localhost 4242
# Consumer
$ nc localhost 4242 | pv > /dev/null
lolput.rb does 42-45 MB/s. It's now much closer to my baseline. Generating a string of zeroes in the kernel is FAST guys!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@JEG2 I didn't do anything beyond profiling it to see if the bottleneck was different. I think I should only have two threads: one for producing messages, and another for IO. IF I was IO-bound, I believe this would effectively circumvent the GIL. However, I'm clearly bound on generating ipsum text.
FWIW, I introduced framing/batching messages because without it the producer was painfully slow.
I added threads on a lark to see if it was marginally faster. My surprise is how much slower it is.