Created
July 14, 2017 17:06
-
-
Save sethdusek/430e3bfa05a802c3a2501dc0564edda6 to your computer and use it in GitHub Desktop.
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
| extern crate libc; | |
| pub mod zc; |
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
| #![feature(test)] | |
| extern crate test; | |
| extern crate zerocopy; | |
| use zerocopy::zc::ZeroCopy; | |
| use test::Bencher; | |
| use std::io::prelude::*; | |
| use std::fs::File; | |
| #[bench] | |
| fn zerocopy(b: &mut Bencher) { | |
| let mut src = File::open("/tmp/foo").unwrap(); | |
| let mut dest = File::create("/tmp/foo.txt").unwrap(); | |
| b.iter(|| { | |
| unsafe { src.copy_to_fd(&mut dest).unwrap() }; | |
| }); | |
| std::fs::remove_file("/tmp/foo.txt"); | |
| } | |
| #[bench] | |
| fn default(b: &mut Bencher) { | |
| let mut src = File::open("/tmp/foo").unwrap(); | |
| let mut dest = File::create("/tmp/foo.txt").unwrap(); | |
| let len = src.metadata().unwrap().len() as usize; | |
| b.iter(|| { | |
| ::std::io::copy(&mut src, &mut dest).unwrap(); | |
| src.seek(::std::io::SeekFrom::Start(0)); | |
| }); | |
| std::fs::remove_file("/tmp/foo.txt"); | |
| } |
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
| use libc::{c_int, splice}; | |
| use std::os::unix::io::AsRawFd; | |
| use std::io::Result; | |
| use std::io::prelude::*; | |
| const __NR_copy_file_range: ::libc::c_long = 326; | |
| unsafe fn copy_file_range(fd_in: c_int, off_in: *mut ::libc::loff_t, fd_out: c_int, off_out: *mut ::libc::loff_t, len: usize, flags: u32) -> i64 { | |
| ::libc::syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags) | |
| } | |
| pub trait ZeroCopy<T> { | |
| unsafe fn copy_to_fd(&mut self, fd: &mut T) -> Result<u64>; | |
| } | |
| /*impl <T> ZeroCopy for T where T: AsRawFd + Read { | |
| unsafe fn copy_to_fd<FD: AsRawFd + Write>(&mut self, fd: &mut FD) -> Result<u64> { | |
| let res = splice(0, ::std::ptr::null_mut(), fd.as_raw_fd(), ::std::ptr::null_mut(), 12, 0); | |
| Ok(res as u64) | |
| } | |
| }*/ | |
| impl ZeroCopy<::std::fs::File> for ::std::fs::File { | |
| unsafe fn copy_to_fd(&mut self, fd: &mut ::std::fs::File) -> Result<u64> { | |
| let len = fd.metadata()?.len() as usize; | |
| let bytes = copy_file_range(self.as_raw_fd(), ::std::ptr::null_mut(), fd.as_raw_fd(), ::std::ptr::null_mut(), len, 0); | |
| if bytes < 0 { | |
| Err(::std::io::Error::last_os_error()) | |
| } | |
| else { Ok(bytes as u64) } | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment