What the program does: I have made a program that simulates a ball in an area made of triangles and many optimizations because it's for high-performance ball path simulation (technically ball path prediction).

Vec3 and Ball definitions:

#[derive(Clone, Copy, Debug)]
pub struct Vec3 {
    pub x: f32,
    pub y: f32,
    pub z: f32,

#[derive(Clone, Copy, Debug)]
pub struct Ball {
    pub time: f32,
    pub location: Vec3,
    pub velocity: Vec3,
    pub angular_velocity: Vec3,
    pub radius: f32,
    pub collision_radius: f32,
    pub moi: f32,

How it works right now: I have a function that takes all of the ball info/game info as well as the desired time to simulate the ball for. It converts the time into the number of game ticks that need to be run to actually simulate the ball for that time. It runs a loop for that number of ticks. For each tick, it calls another function, step(game: &mut Game, dt: f32). This runs all of the physics that would advance the game that one tick (CPU only, no graphical output whatsoever or GPU involvement.) I then throw the ball data into a Box and throw that into a Vec. This is so, when the Vec is returned, I basically have the predicted path of the ball, from game tick to game tick.

The function:

pub fn get_ball_prediction_struct_for_time(game: &mut Game, time: &f32) -> BallPrediction {
    let num_slices = (time / Ball::SIMULATION_DT).round() as usize;
    let mut slices = Vec::with_capacity(num_slices);

    for _ in 0..num_slices {
        Ball::step(game, Ball::SIMULATION_DT);

    BallPrediction {

My question: Is putting the ball into a box and putting that into a Vec the best, most efficient way to do this? Is it possible for me to rather clone the balls into the stack (I believe Box stores it on the heap?) but then Vec stores stuff on the heap anyway, so does that even matter? How can I minimize moving all the data around?

I'm also new-er to Rust, so insight into Rust and its conventions is appreciated! I can share as might insight to the program as needed, this is an open-source hobby project of mine.

  • 1
    \$\begingroup\$ There isn't enough information here to determine “most efficient”. We'll need to see the definition of Ball at least; preferably a complete runnable program. It's very likely that you should not be trying to “minimize moving”, and the Box is doing you no good, but more details of your data will help determine that. (And in the end, the only way to be sure about performance is to benchmark, not to read the code.) \$\endgroup\$
    – Kevin Reid
    Nov 12, 2021 at 19:35
  • \$\begingroup\$ @KevinReid Sure! Here's the github repo with tests - github.com/VirxEC/rl_ball_sym - it's also a crate on crates.io. The closest test to that is fast_predict_soccar, where you can really just swap out the functions (line 362) and put in a value for time. \$\endgroup\$
    – VirxEC
    Nov 12, 2021 at 19:46
  • \$\begingroup\$ I also added type definitions for Ball (and Vec3 in that.) \$\endgroup\$
    – VirxEC
    Nov 12, 2021 at 19:48
  • \$\begingroup\$ I actually just added a test called fast_predict_custom_soccar, it's in the repo for anyone to run. \$\endgroup\$
    – VirxEC
    Nov 12, 2021 at 20:02

1 Answer 1


welcome to the Rust community.

A Vec is a continuous slice of heap memory. A Box is a fixed-size portion of heap memory (except for boxed DSTs). A Box within a Vec is entirely unnecessary (except in extreme cases when you are moving around huge structs). Putting a Box inside a Vec is like wrapping your items in two layers of packaging. This overhead is quite small, though: one heap allocation per item.

Don't worry about copying things onto the stack. The stack is efficient and Rust/LLVM will optimize moves of your values.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.