Skip to content

Commit 0f39dc7

Browse files
committed
std: inline many of the Writer/Reader methods
This allows llvm to optimize away much of the overhead from using the MemReader/MemWriters. My benchmarks showed it to shave 15% off of my in progress serialization/json encoding.
1 parent 76371d1 commit 0f39dc7

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

src/libstd/io/mem.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ pub struct MemWriter {
5959

6060
impl MemWriter {
6161
/// Create a new `MemWriter`.
62+
#[inline]
6263
pub fn new() -> MemWriter {
6364
MemWriter::with_capacity(128)
6465
}
6566
/// Create a new `MemWriter`, allocating at least `n` bytes for
6667
/// the internal buffer.
68+
#[inline]
6769
pub fn with_capacity(n: uint) -> MemWriter {
6870
MemWriter { buf: Vec::with_capacity(n), pos: 0 }
6971
}
@@ -73,13 +75,16 @@ impl MemWriter {
7375
///
7476
/// No method is exposed for acquiring a mutable reference to the buffer
7577
/// because it could corrupt the state of this `MemWriter`.
78+
#[inline]
7679
pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
7780

7881
/// Unwraps this `MemWriter`, returning the underlying buffer
82+
#[inline]
7983
pub fn unwrap(self) -> Vec<u8> { self.buf }
8084
}
8185

8286
impl Writer for MemWriter {
87+
#[inline]
8388
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
8489
// Make sure the internal buffer is as least as big as where we
8590
// currently are
@@ -112,7 +117,10 @@ impl Writer for MemWriter {
112117
}
113118

114119
impl Seek for MemWriter {
120+
#[inline]
115121
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
122+
123+
#[inline]
116124
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
117125
let new = try!(combine(style, self.pos, self.buf.len(), pos));
118126
self.pos = new as uint;
@@ -140,6 +148,7 @@ pub struct MemReader {
140148
impl MemReader {
141149
/// Creates a new `MemReader` which will read the buffer given. The buffer
142150
/// can be re-acquired through `unwrap`
151+
#[inline]
143152
pub fn new(buf: Vec<u8>) -> MemReader {
144153
MemReader {
145154
buf: buf,
@@ -150,20 +159,24 @@ impl MemReader {
150159
/// Tests whether this reader has read all bytes in its buffer.
151160
///
152161
/// If `true`, then this will no longer return bytes from `read`.
162+
#[inline]
153163
pub fn eof(&self) -> bool { self.pos >= self.buf.len() }
154164

155165
/// Acquires an immutable reference to the underlying buffer of this
156166
/// `MemReader`.
157167
///
158168
/// No method is exposed for acquiring a mutable reference to the buffer
159169
/// because it could corrupt the state of this `MemReader`.
170+
#[inline]
160171
pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
161172

162173
/// Unwraps this `MemReader`, returning the underlying buffer
174+
#[inline]
163175
pub fn unwrap(self) -> Vec<u8> { self.buf }
164176
}
165177

166178
impl Reader for MemReader {
179+
#[inline]
167180
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
168181
if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
169182

@@ -182,7 +195,10 @@ impl Reader for MemReader {
182195
}
183196

184197
impl Seek for MemReader {
198+
#[inline]
185199
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
200+
201+
#[inline]
186202
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
187203
let new = try!(combine(style, self.pos, self.buf.len(), pos));
188204
self.pos = new as uint;
@@ -191,13 +207,16 @@ impl Seek for MemReader {
191207
}
192208

193209
impl Buffer for MemReader {
210+
#[inline]
194211
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
195212
if self.pos < self.buf.len() {
196213
Ok(self.buf.slice_from(self.pos))
197214
} else {
198215
Err(io::standard_error(io::EndOfFile))
199216
}
200217
}
218+
219+
#[inline]
201220
fn consume(&mut self, amt: uint) { self.pos += amt; }
202221
}
203222

@@ -227,6 +246,7 @@ pub struct BufWriter<'a> {
227246
impl<'a> BufWriter<'a> {
228247
/// Creates a new `BufWriter` which will wrap the specified buffer. The
229248
/// writer initially starts at position 0.
249+
#[inline]
230250
pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
231251
BufWriter {
232252
buf: buf,
@@ -236,6 +256,7 @@ impl<'a> BufWriter<'a> {
236256
}
237257

238258
impl<'a> Writer for BufWriter<'a> {
259+
#[inline]
239260
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
240261
// return an error if the entire write does not fit in the buffer
241262
let max_size = self.buf.len();
@@ -254,7 +275,10 @@ impl<'a> Writer for BufWriter<'a> {
254275
}
255276

256277
impl<'a> Seek for BufWriter<'a> {
278+
#[inline]
257279
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
280+
281+
#[inline]
258282
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
259283
let new = try!(combine(style, self.pos, self.buf.len(), pos));
260284
self.pos = new as uint;
@@ -282,6 +306,7 @@ pub struct BufReader<'a> {
282306

283307
impl<'a> BufReader<'a> {
284308
/// Creates a new buffered reader which will read the specified buffer
309+
#[inline]
285310
pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
286311
BufReader {
287312
buf: buf,
@@ -292,10 +317,12 @@ impl<'a> BufReader<'a> {
292317
/// Tests whether this reader has read all bytes in its buffer.
293318
///
294319
/// If `true`, then this will no longer return bytes from `read`.
320+
#[inline]
295321
pub fn eof(&self) -> bool { self.pos >= self.buf.len() }
296322
}
297323

298324
impl<'a> Reader for BufReader<'a> {
325+
#[inline]
299326
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
300327
if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
301328

@@ -314,7 +341,10 @@ impl<'a> Reader for BufReader<'a> {
314341
}
315342

316343
impl<'a> Seek for BufReader<'a> {
344+
#[inline]
317345
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
346+
347+
#[inline]
318348
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
319349
let new = try!(combine(style, self.pos, self.buf.len(), pos));
320350
self.pos = new as uint;
@@ -323,22 +353,27 @@ impl<'a> Seek for BufReader<'a> {
323353
}
324354

325355
impl<'a> Buffer for BufReader<'a> {
356+
#[inline]
326357
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
327358
if self.pos < self.buf.len() {
328359
Ok(self.buf.slice_from(self.pos))
329360
} else {
330361
Err(io::standard_error(io::EndOfFile))
331362
}
332363
}
364+
365+
#[inline]
333366
fn consume(&mut self, amt: uint) { self.pos += amt; }
334367
}
335368

336369
#[cfg(test)]
337370
mod test {
371+
extern crate test;
338372
use prelude::*;
339373
use super::*;
340374
use io::*;
341375
use io;
376+
use self::test::Bencher;
342377
use str::StrSlice;
343378

344379
#[test]
@@ -571,4 +606,59 @@ mod test {
571606
assert!(r.read_at_least(buf.len(), buf).is_err());
572607
assert_eq!(buf.as_slice(), &[7, 8, 6]);
573608
}
609+
610+
#[bench]
611+
fn bench_mem_writer(b: &mut Bencher) {
612+
b.iter(|| {
613+
let mut wr = MemWriter::new();
614+
for _i in range(0, 10) {
615+
wr.write([5, .. 10]).unwrap();
616+
}
617+
assert_eq!(wr.unwrap().as_slice(), [5, .. 100].as_slice());
618+
});
619+
}
620+
621+
#[bench]
622+
fn bench_mem_reader(b: &mut Bencher) {
623+
b.iter(|| {
624+
let buf = Vec::from_slice([5 as u8, ..100]);
625+
{
626+
let mut rdr = MemReader::new(buf);
627+
for _i in range(0, 10) {
628+
let mut buf = [0 as u8, .. 10];
629+
rdr.read(buf).unwrap();
630+
assert_eq!(buf.as_slice(), [5, .. 10].as_slice());
631+
}
632+
}
633+
});
634+
}
635+
636+
#[bench]
637+
fn bench_buf_writer(b: &mut Bencher) {
638+
b.iter(|| {
639+
let mut buf = [0 as u8, ..100];
640+
{
641+
let mut wr = BufWriter::new(buf);
642+
for _i in range(0, 10) {
643+
wr.write([5, .. 10]).unwrap();
644+
}
645+
}
646+
assert_eq!(buf.as_slice(), [5, .. 100].as_slice());
647+
});
648+
}
649+
650+
#[bench]
651+
fn bench_buf_reader(b: &mut Bencher) {
652+
b.iter(|| {
653+
let buf = [5 as u8, ..100];
654+
{
655+
let mut rdr = BufReader::new(buf);
656+
for _i in range(0, 10) {
657+
let mut buf = [0 as u8, .. 10];
658+
rdr.read(buf).unwrap();
659+
assert_eq!(buf.as_slice(), [5, .. 10].as_slice());
660+
}
661+
}
662+
});
663+
}
574664
}

0 commit comments

Comments
 (0)