Skip to content

Instantly share code, notes, and snippets.

@brendanzab
Created October 28, 2012 03:50
Show Gist options
  • Select an option

  • Save brendanzab/3967417 to your computer and use it in GitHub Desktop.

Select an option

Save brendanzab/3967417 to your computer and use it in GitHub Desktop.
Vector struct index operator performance
extern mod std;
use std::time::precise_time_ns;
use cast::{reinterpret_cast, transmute};
use ptr::to_unsafe_ptr;
pub struct Vec4 { x: float, y: float, z: float, w: float }
pub struct VecMatch { x: float, y: float, z: float, w: float }
pub impl VecMatch: Index<uint, float> {
#[inline(always)]
pure fn index(i: uint) -> float {
match i {
0 => self.x,
1 => self.y,
2 => self.z,
3 => self.w,
_ => fail(~"Vector index out of bounds.")
}
}
}
pub struct VecReinterpret { x: float, y: float, z: float, w: float }
pub impl VecReinterpret: Index<uint, float> {
#[inline(always)]
pure fn index(i: uint) -> float unsafe {
(reinterpret_cast::<VecReinterpret, [float * 4]>(&self))[i]
}
}
pub struct VecTransmute { x: float, y: float, z: float, w: float }
pub impl VecTransmute: Index<uint, float> {
#[inline(always)]
pure fn index(i: uint) -> float unsafe {
(transmute::<VecTransmute, [float * 4]>(self))[i]
}
}
pub struct VecBufSlice { x: float, y: float, z: float, w: float }
pub impl VecBufSlice: Index<uint, float> {
#[inline(always)]
pure fn index(i: uint) -> float unsafe {
do vec::raw::buf_as_slice(
transmute::<*VecBufSlice, *float>(
to_unsafe_ptr(&self)), 4) |slice| { slice[i] }
}
}
fn main() {
let n_tests = 100000;
let v = Vec4 { x: 1f, y: 2f, z: 3f, w: 4f };
let vfield_avg = do test_avg_time_ns(n_tests) {
// io::println(fmt!("[ %?, %?, %?, %? ]", v.x, v.y, v.z, v.w));
assert(v.x == 1f);
assert(v.y == 2f);
assert(v.z == 3f);
assert(v.w == 4f);
};
io::println(fmt!("Vec4.x,y,z,w: [%d]", vfield_avg as int));
let vmatch = VecMatch { x: 1f, y: 2f, z: 3f, w: 4f };
let vindex_avg = do test_avg_time_ns(n_tests) {
assert(vmatch[0] == 1f);
assert(vmatch[1] == 2f);
assert(vmatch[2] == 3f);
assert(vmatch[3] == 4f);
};
let vreint = VecReinterpret { x: 1f, y: 2f, z: 3f, w: 4f };
let vreint_avg = do test_avg_time_ns(n_tests) {
assert(vreint[0] == 1f);
assert(vreint[1] == 2f);
assert(vreint[2] == 3f);
assert(vreint[3] == 4f);
};
let vtrans = VecTransmute { x: 1f, y: 2f, z: 3f, w: 4f };
let vtrans_avg = do test_avg_time_ns(n_tests) {
assert(vtrans[0] == 1f);
assert(vtrans[1] == 2f);
assert(vtrans[2] == 3f);
assert(vtrans[3] == 4f);
};
let vbufslice = VecBufSlice { x: 1f, y: 2f, z: 3f, w: 4f };
let vbufslice_avg = do test_avg_time_ns(n_tests) {
assert(vbufslice[0] == 1f);
assert(vbufslice[1] == 2f);
assert(vbufslice[2] == 3f);
assert(vbufslice[3] == 4f);
};
let min = [vfield_avg, vindex_avg, vreint_avg, vtrans_avg, vbufslice_avg].min();
io::println(fmt!("Vec4.x,y,z,w: %d = %d", vfield_avg as int, (vfield_avg - min) as int));
io::println(fmt!("VecMatch[i]: %d = %d", vindex_avg as int, (vindex_avg - min) as int));
io::println(fmt!("VecReinterpret[i]: %d = %d", vreint_avg as int, (vreint_avg - min) as int));
io::println(fmt!("VecTransmute[i]: %d = %d", vtrans_avg as int, (vtrans_avg - min) as int));
io::println(fmt!("VecBufSlice[i]: %d = %d", vbufslice_avg as int, (vbufslice_avg - min) as int));
}
fn test_avg_time_ns(n: uint, f: fn&()) -> u64 {
let mut total = 0;
for n.times {
let start_time = precise_time_ns();
f();
total += precise_time_ns() - start_time;
}
return total / (n as u64);
}
% ./vector_structs
Vec4.x,y,z,w: [755]
Vec4.x,y,z,w: 755 = 33
VecMatch[i]: 723 = 1
VecReinterpret[i]: 722 = 0
VecTransmute[i]: 734 = 12
VecBufSlice[i]: 763 = 41
% ./vector_structs
Vec4.x,y,z,w: [762]
Vec4.x,y,z,w: 762 = 35
VecMatch[i]: 757 = 30
VecReinterpret[i]: 729 = 2
VecTransmute[i]: 744 = 17
VecBufSlice[i]: 727 = 0
% ./vector_structs
Vec4.x,y,z,w: [760]
Vec4.x,y,z,w: 760 = 38
VecMatch[i]: 734 = 12
VecReinterpret[i]: 727 = 5
VecTransmute[i]: 733 = 11
VecBufSlice[i]: 722 = 0
% ./vector_structs
Vec4.x,y,z,w: [820]
Vec4.x,y,z,w: 820 = 89
VecMatch[i]: 745 = 14
VecReinterpret[i]: 751 = 20
VecTransmute[i]: 768 = 37
VecBufSlice[i]: 731 = 0
% ./vector_structs
Vec4.x,y,z,w: [1188]
Vec4.x,y,z,w: 1188 = 214
VecMatch[i]: 1025 = 51
VecReinterpret[i]: 988 = 14
VecTransmute[i]: 1007 = 33
VecBufSlice[i]: 974 = 0
% ./vector_structs
Vec4.x,y,z,w: [731]
Vec4.x,y,z,w: 731 = 8
VecMatch[i]: 753 = 30
VecReinterpret[i]: 723 = 0
VecTransmute[i]: 739 = 16
VecBufSlice[i]: 743 = 20
% ./vector_structs
Vec4.x,y,z,w: [738]
Vec4.x,y,z,w: 738 = 10
VecMatch[i]: 734 = 6
VecReinterpret[i]: 762 = 34
VecTransmute[i]: 742 = 14
VecBufSlice[i]: 728 = 0
% ./vector_structs
Vec4.x,y,z,w: [743]
Vec4.x,y,z,w: 743 = 40
VecMatch[i]: 709 = 6
VecReinterpret[i]: 703 = 0
VecTransmute[i]: 710 = 7
VecBufSlice[i]: 706 = 3
% ./vector_structs
Vec4.x,y,z,w: [773]
Vec4.x,y,z,w: 773 = 27
VecMatch[i]: 848 = 102
VecReinterpret[i]: 776 = 30
VecTransmute[i]: 867 = 121
VecBufSlice[i]: 746 = 0
% ./vector_structs
Vec4.x,y,z,w: [752]
Vec4.x,y,z,w: 752 = 33
VecMatch[i]: 763 = 44
VecReinterpret[i]: 736 = 17
VecTransmute[i]: 730 = 11
VecBufSlice[i]: 719 = 0
% ./vector_structs
Vec4.x,y,z,w: [794]
Vec4.x,y,z,w: 794 = 79
VecMatch[i]: 736 = 21
VecReinterpret[i]: 715 = 0
VecTransmute[i]: 720 = 5
VecBufSlice[i]: 725 = 10
% ./vector_structs
Vec4.x,y,z,w: [1155]
Vec4.x,y,z,w: 1155 = 426
VecMatch[i]: 738 = 9
VecReinterpret[i]: 745 = 16
VecTransmute[i]: 729 = 0
VecBufSlice[i]: 767 = 38
% ./vector_structs
Vec4.x,y,z,w: [795]
Vec4.x,y,z,w: 795 = 78
VecMatch[i]: 735 = 18
VecReinterpret[i]: 809 = 92
VecTransmute[i]: 779 = 62
VecBufSlice[i]: 717 = 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment