Learning Rust, this code in C++ runs in a semi instant way, where in Rust it's way slower. What could be the bottle neck?

69 points AdearienRDDT
//color.rs
pub fn write_color(out: &mut io::BufWriter<io::Stdout>, pixel_color: &Color) {
    let range_factor: f64 = 255.999;

    let rbyte = (range_factor * pixel_color.x()) as i32;
    let gbyte = (range_factor * pixel_color.y()) as i32;
    let bbyte = (range_factor * pixel_color.z()) as i32;

    writeln!(out, "{} {} {}", rbyte, gbyte, bbyte).unwrap();
}


fn write_image() {
    let aspect_ratio = 16.0 / 9.0;
    let image_width = 400;
    let image_height = (image_width as f64 / aspect_ratio) as i32;

    let focal_length = 1.0;
    let viewport_height = 2.0;
    let viewport_width = viewport_height * aspect_ratio;
    let camera_center = Vec3::with_values(0.0, 0.0, 0.0);

    let viewport_u = Vec3::with_values(viewport_width, 0.0, 0.0);
    let viewport_v = Vec3::with_values(0.0, -viewport_height, 0.0);

    let pixel_delta_u = viewport_u / image_width as f64;
    let pixel_delta_v = viewport_v / image_height as f64;

    let viewport_upperleft = camera_center
        - Vec3::with_values(0.0, 0.0, focal_length)
        - viewport_u / 2.0
        - viewport_v / 2.0;

    let pixel00_loc = viewport_upperleft + 0.5 * (pixel_delta_u + pixel_delta_v);

    println!("P3\

{} {}
255", image_width, image_height);

    let writer = io::BufWriter::new(io::stdout());

    for j in 0..image_height {
        eprint!("\\rScanlines remaining: {} ", image_height - j);

        for i in 0..image_width {
            let pixel_center =
                pixel00_loc + (i as f64 * pixel_delta_u) + (j as f64 * pixel_delta_v);
            let ray_direction = pixel_center - camera_center;
            let r = Ray::with_values(camera_center, ray_direction);

            let pixel_color = ray_color(&r);
            color::write_color(&mut writer, &pixel_color);
        }
    }
}

Here is the C++ code:

// color.hpp

void write_color(std::ostream &out, const color &pixel_color) noexcept {
  auto r = pixel_color.x();
  auto g = pixel_color.y();
  auto b = pixel_color.z();
  // From [0, 1] range to [0, 255];
  int rbyte = static_cast<int>(255.999 * r);
  int gbyte = static_cast<int>(255.999 * g);
  int bbyte = static_cast<int>(255.999 * b);

  out << rbyte << ' ' << gbyte << ' ' << bbyte << '\

';
}

int main(int argc, char *argv[]) {

  auto aspect_ratio = 16.0 / 9.0;
  int image_width = 400;

  int image_height = static_cast<int>(image_width / aspect_ratio);
  image_height = (image_height < 1) ? 1 : image_height;

  // Camera setup

  auto focal_length = 1.0;
  auto viewport_height = 2.0;
  auto viewport_width =
      viewport_height * (static_cast<double>(image_width) / image_height);
  auto camera_center = point3{0, 0, 0};

  auto viewport_u = vec3{viewport_width, 0, 0};
  auto viewport_v = vec3{0, -viewport_height, 0};

  // Delta vectors
  auto pixel_delta_u = viewport_u / image_width;
  auto pixel_delta_v = viewport_v / image_height;

  // location of the upper left pixel;

  auto viewport_upperleft = camera_center - vec3{0, 0, focal_length} -
                            viewport_u / 2 - viewport_v / 2;

  auto pixel00_loc = viewport_upperleft + 0.5 * (pixel_delta_u + pixel_delta_v);

  std::cout << "P3\

" << image_width << ' ' << image_height << "
255
";

  for (int j = 0; j < image_height; ++j) {
    std::clog << "\\rScanlines remaining: " << (image_height - j) << ' '
              << std::flush;
    for (int i = 0; i < image_width; ++i) {
      /* auto pixel_color = color(static_cast<double>(i) / image_width - 1,
                               static_cast<double>(j) / image_height - 1, 0); */

      auto pixel_center =
          pixel00_loc + (i * pixel_delta_u) + (j * pixel_delta_v);
      auto ray_direction = pixel_center - camera_center;
      ray r{camera_center, ray_direction};

      color pixel_color = ray_color(r);

      write_color(std::cout, pixel_color);
    }
  }

  return 0;
}

IT'S FIXED AS OF 1:19 PM EST!!!!

Thanks to u/slamb for the solution!