commit 80ef6c1054dda705e6a4dd4a527ee81cf06115a9
parent ccbf1e22718c6d1d30caecb647c878480e6377d5
Author: Bradley Gannon <bradley@bradleygannon.com>
Date: Thu, 18 Dec 2025 18:26:02 -0500
Add some performance tracking and optimizations
Diffstat:
4 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/.cargo/config.toml b/.cargo/config.toml
@@ -0,0 +1,2 @@
+[build]
+rustflags = ["-C", "target-cpu=native"]
diff --git a/Cargo.toml b/Cargo.toml
@@ -4,3 +4,8 @@ version = "0.1.0"
edition = "2024"
[dependencies]
+
+[profile.release]
+codegen-units = 1
+lto = "fat"
+panic = "abort"
diff --git a/src/camera.rs b/src/camera.rs
@@ -1,9 +1,12 @@
+use std::time::Instant;
+
use crate::{
color::LinearColor, hittable::Hittable, interval::Interval, random::RandomNumberGenerator,
ray::Ray, vec3::Vec3,
};
-struct Image {
+#[derive(Clone, Debug, PartialEq, PartialOrd)]
+pub struct Image {
data: Vec<Vec<LinearColor>>,
}
@@ -17,7 +20,7 @@ impl Image {
data: vec![vec![LinearColor::default(); width]; height],
}
}
- fn to_ppm_string(&self) -> String {
+ pub fn to_ppm_string(&self) -> String {
let mut output = "P3\n".to_string();
let height = self.data.len();
let width = if height > 0 { self.data[0].len() } else { 0 };
@@ -143,10 +146,12 @@ impl Camera {
}
}
- pub fn render(&mut self, world: &[Box<dyn Hittable>]) {
+ pub fn render(&mut self, world: &[Box<dyn Hittable>]) -> Image {
let mut image = Image::new(self.image_width, self.image_height);
- for i in 0..self.image_width {
- for j in 0..self.image_height {
+ let image_start = Instant::now();
+ for j in 0..self.image_height {
+ let line_start = Instant::now();
+ for i in 0..self.image_width {
let mut pixel_color = LinearColor::new(0., 0., 0.);
for _ in 0..self.samples_per_pixel {
let r = self.get_ray(i, j);
@@ -155,8 +160,22 @@ impl Camera {
}
image.data[j][i] = pixel_color;
}
+ let line_duration = line_start.elapsed();
+ let pixels_per_second = self.image_width as f64 / line_duration.as_secs_f64();
+ eprint!(
+ "\rLine {:>5}/{:>5} ({:.2} pixels / second) ",
+ j + 1,
+ self.image_height,
+ pixels_per_second
+ );
}
- println!("{}", image.to_ppm_string());
+ let image_duration = image_start.elapsed();
+ eprintln!(
+ "\rDone in {:.1} seconds ({:.1} pixels / second) ",
+ image_duration.as_secs_f64(),
+ self.image_width as f64 * self.image_height as f64 / image_duration.as_secs_f64()
+ );
+ image
}
fn ray_color(&mut self, r: &Ray, world: &[Box<dyn Hittable>], depth: usize) -> LinearColor {
diff --git a/src/main.rs b/src/main.rs
@@ -80,7 +80,7 @@ fn main() {
let config = CameraConfig {
aspect_ratio: 16. / 9.,
image_width: 1200,
- samples_per_pixel: 500,
+ samples_per_pixel: 300,
max_bounces: 50,
field_of_view_degrees: 20.,
look_from: Vec3::new(13., 2., 3.),
@@ -91,5 +91,6 @@ fn main() {
rng,
};
let mut camera = Camera::new(&config);
- camera.render(&world);
+ let image = camera.render(&world);
+ println!("{}", image.to_ppm_string());
}