Skip to content

Commit

Permalink
Enhance performance by 15%
Browse files Browse the repository at this point in the history
  • Loading branch information
ia0 committed Jan 1, 2016
1 parent 9ad74a2 commit 43f3cf3
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Patch

- Enhance performance by 15%.
- Document the commands to build the example and run the benchmarks.
- Compare performance with the `base64` crate.
- Add `generic` to the crate keywords.
Expand Down
6 changes: 4 additions & 2 deletions src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::{error, fmt};

use base::{Base, len, enc, dec};
use tool::{div_ceil, chunk, chunk_mut};
use tool::{div_ceil, chunk, chunk_mut, chunk_unchecked, chunk_mut_unchecked};

use self::Error::*;

Expand Down Expand Up @@ -89,7 +89,9 @@ pub fn decode_mut<B: Base>(base: &B, input: &[u8], output: &mut [u8]) -> Result<
assert_eq!(output.len(), decode_len(base, ilen));
let n = ilen / dec - 1;
for i in 0 .. n {
try!(block(base, chunk(input, dec, i), chunk_mut(output, enc, i))
let input = unsafe { chunk_unchecked(input, dec, i) };
let output = unsafe { chunk_mut_unchecked(output, enc, i) };
try!(block(base, input, output)
.map_err(|e| e.shift(dec * i)));
}
last_block(base, chunk(input, dec, n), chunk_mut(output, enc, n))
Expand Down
6 changes: 4 additions & 2 deletions src/encode.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Generic encoding module.

use base::{Base, mask, len, enc, dec};
use tool::{div_ceil, chunk, chunk_mut};
use tool::{div_ceil, chunk_unchecked, chunk_mut_unchecked};

fn block<B: Base>(base: &B, input: &[u8], output: &mut [u8]) {
let mut x = 0u64; // This is enough because `base.len() <= 40`.
Expand Down Expand Up @@ -66,7 +66,9 @@ pub fn encode_mut<B: Base>(base: &B, input: &[u8], output: &mut [u8]) {
assert_eq!(output.len(), olen);
let n = ilen / enc;
for i in 0 .. n {
block(base, chunk(input, enc, i), chunk_mut(output, dec, i));
let input = unsafe { chunk_unchecked(input, enc, i) };
let output = unsafe { chunk_mut_unchecked(output, dec, i) };
block(base, input, output);
}
last_block(base, &input[enc * n ..], &mut output[dec * n ..]);
}
Expand Down
18 changes: 16 additions & 2 deletions src/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,24 @@ pub fn div_ceil(x: usize, m: usize) -> usize {
(x + m - 1) / m
}

pub unsafe fn chunk_unchecked(x: &[u8], n: usize, i: usize) -> &[u8] {
let ptr = x.as_ptr().offset((n * i) as isize);
::std::slice::from_raw_parts(ptr, n)
}

pub unsafe fn chunk_mut_unchecked
(x: &mut [u8], n: usize, i: usize) -> &mut [u8]
{
let ptr = x.as_mut_ptr().offset((n * i) as isize);
::std::slice::from_raw_parts_mut(ptr, n)
}

pub fn chunk(x: &[u8], n: usize, i: usize) -> &[u8] {
&x[n * i .. n * (i + 1)]
assert!(n * (i + 1) <= x.len());
unsafe { chunk_unchecked(x, n, i) }
}

pub fn chunk_mut(x: &mut [u8], n: usize, i: usize) -> &mut [u8] {
&mut x[n * i .. n * (i + 1)]
assert!(n * (i + 1) <= x.len());
unsafe { chunk_mut_unchecked(x, n, i) }
}

0 comments on commit 43f3cf3

Please sign in to comment.