Skip to content

Commit efd6aaa

Browse files
committed
Merge pull request #4 from github/buffered-write
introduce a new buffered writer method
2 parents dd6090e + 2983829 commit efd6aaa

File tree

5 files changed

+77
-4
lines changed

5 files changed

+77
-4
lines changed

bench/memsize.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'bert'
2+
require 'objspace'
3+
4+
large = ["abc" * 1000] * 10000
5+
6+
def write_berp(output, ruby)
7+
data = BERT.encode(ruby)
8+
output.write([data.bytesize].pack("N"))
9+
output.write(data)
10+
end
11+
12+
def write_berp2(output, ruby)
13+
data = BERT.encode_to_buffer(ruby)
14+
output.write([data.bytesize].pack("N"))
15+
data.write_to output
16+
end
17+
18+
socket = File.open File::NULL, 'wb' do |f|
19+
GC.start; GC.start; GC.start; GC.disable
20+
21+
before = ObjectSpace.memsize_of_all(String)
22+
write_berp f, large
23+
p :ORIGINAL => ObjectSpace.memsize_of_all(String) - before
24+
25+
GC.start; GC.start; GC.start; GC.disable
26+
before = ObjectSpace.memsize_of_all(String)
27+
write_berp2 f, large
28+
p :NEW => ObjectSpace.memsize_of_all(String) - before
29+
end

lib/bert/bert.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ def self.encode(ruby)
33
Encoder.encode(ruby)
44
end
55

6+
def self.encode_to_buffer(ruby)
7+
Encoder.encode_to_buffer(ruby)
8+
end
9+
610
def self.decode(bert)
711
Decoder.decode(bert)
812
end
@@ -18,4 +22,4 @@ def inspect
1822
"t#{super}"
1923
end
2024
end
21-
end
25+
end

lib/bert/encode.rb

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,44 @@ def initialize(out)
4949
self.out = out
5050
end
5151

52+
class Buffer
53+
def initialize
54+
@buf = []
55+
end
56+
57+
def write(str)
58+
@buf << str
59+
end
60+
61+
def write_to(io)
62+
@buf.each { |x| io.write x }
63+
end
64+
65+
def bytesize
66+
@buf.map(&:bytesize).inject :+
67+
end
68+
end
69+
70+
def self.encode_to_buffer(data)
71+
io = Buffer.new
72+
encode_data data, io
73+
io
74+
end
75+
5276
def self.encode(data)
77+
buf = encode_to_buffer data
5378
io = StringIO.new
5479
io.set_encoding('binary') if io.respond_to?(:set_encoding)
80+
buf.write_to io
81+
io.string
82+
end
5583

84+
def self.encode_data(data, io)
5685
if version == :v2
5786
Encode::V2.new(io).write_any(data)
5887
else
5988
new(io).write_any(data)
6089
end
61-
62-
io.string
6390
end
6491

6592
def write_any obj

lib/bert/encoder.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ def self.encode(ruby)
99
Encode.encode(complex_ruby)
1010
end
1111

12+
def self.encode_to_buffer(ruby)
13+
complex_ruby = convert(ruby)
14+
Encode.encode_to_buffer(complex_ruby)
15+
end
16+
1217
# Convert complex Ruby form in simple Ruby form.
1318
# +item+ is the Ruby object to convert
1419
#
@@ -42,4 +47,4 @@ def self.convert(item)
4247
end
4348
end
4449
end
45-
end
50+
end

test/bert_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ class BertTest < Test::Unit::TestCase
4444
assert_equal @bert, BERT.encode(@ruby)
4545
end
4646

47+
should "encode with buffer" do
48+
buf = BERT.encode_to_buffer(@ruby)
49+
io = StringIO.new
50+
io.set_encoding 'binary'
51+
buf.write_to io
52+
assert_equal @bert, io.string
53+
end
54+
4755
should "ebin" do
4856
assert_equal @ebin, BERT.ebin(@bert)
4957
end

0 commit comments

Comments
 (0)