use rust_xlsxwriter::{Workbook, XlsxError};
use std::{env, time::Instant};
use std::alloc::{GlobalAlloc, Layout, System};
use std::sync::atomic::{AtomicU64, Ordering};
pub struct Trallocator<A: GlobalAlloc>(pub A, AtomicU64);
unsafe impl<A: GlobalAlloc> GlobalAlloc for Trallocator<A> {
unsafe fn alloc(&self, l: Layout) -> *mut u8 {
unsafe {
self.1.fetch_add(l.size() as u64, Ordering::SeqCst);
self.0.alloc(l)
}
}
unsafe fn dealloc(&self, ptr: *mut u8, l: Layout) {
unsafe {
self.0.dealloc(ptr, l);
self.1.fetch_sub(l.size() as u64, Ordering::SeqCst);
}
}
}
impl<A: GlobalAlloc> Trallocator<A> {
pub const fn new(a: A) -> Self {
Trallocator(a, AtomicU64::new(0))
}
pub fn reset(&self) {
self.1.store(0, Ordering::SeqCst);
}
pub fn get(&self) -> u64 {
self.1.load(Ordering::SeqCst)
}
}
#[global_allocator]
static GLOBAL: Trallocator<System> = Trallocator::new(System);
fn main() -> Result<(), XlsxError> {
let args: Vec<String> = env::args().collect();
let col_max = 50;
let row_max = match args.get(1) {
Some(arg) => arg.parse::<u32>().unwrap_or(4_000),
None => 4_000,
};
#[cfg(feature = "constant_memory")]
let constant_memory = args.get(2).is_some();
#[cfg(not(feature = "constant_memory"))]
let constant_memory = false;
GLOBAL.reset();
let start_time = Instant::now();
let mut workbook = Workbook::new();
let worksheet = if constant_memory {
#[cfg(feature = "constant_memory")]
let worksheet = workbook.add_worksheet_with_constant_memory();
#[cfg(not(feature = "constant_memory"))]
let worksheet = workbook.add_worksheet();
worksheet
} else {
workbook.add_worksheet()
};
for row in 0..row_max {
for col in 0..col_max {
if col % 2 == 1 {
worksheet.write_string(row, col, "Foo")?;
} else {
worksheet.write_number(row, col, 12345.0)?;
}
}
}
workbook.save("rust_perf_test.xlsx")?;
let time = (start_time.elapsed().as_millis() as f64) / 1000.0;
let memory = (GLOBAL.get() as f64) / 1_000_000.0;
println!("Wrote: {row_max} rows x {col_max} cols. Constant memory = {constant_memory}.");
println!("Time: {time:.3} seconds.");
println!("Memory: {memory:.3} MB.");
Ok(())
}