Variable (String/Vector/Map/etc...) created in a loop will keep de+allocating memory?

Hi (I'm new to Rust)

I'm wondering if, from the point of view of memory de/allocation, it's better to create a Vector/Map/String/etc... outside a loop (and then calling ".clear()" inside the loop), than to directly create it inside the loop?

Example 1 - vector created inside the loop:

fn main()
{
	let mut loop_counter:u8 = 0;
	while loop_counter < 3
	{
		let mut myvec:Vec<u8> = Vec::new(); //HERE I CREATE MY VECTOR!
		//Start-Do something with "myvec"
		for _ in 0..3
		{
			myvec.push(0);
		}
		//End-Doing something with "myvec"
		
		loop_counter += 1;
	}
}

Example 2 - vector created outside the loop:

fn main()
{
	let mut myvec:Vec<u8> = Vec::new(); //HERE I CREATE MY VECTOR!
	let mut loop_counter:u8 = 0;
	while loop_counter < 3
	{
		myvec.clear(); //HERE I CLEAR ALL THE CONTENTS OF THE VECTOR!
		
		//Start-Do something with "myvec"
		for _ in 0..3
		{
			myvec.push(0);
		}
		//End-Doing something with "myvec"
		
		loop_counter += 1;
	}
}
  • Variant #1 is easy as I don't have to to think about this stuff, but I feel like that it will keep freeing&allocating "myvec" during each loop?

  • Variant #2 is maybe better (faster and/or puts less pressure on the system?) as "myvec.clear()" might keep the allocated memory during multiple loops (and only allocate more if needed) therefore generating less system calls to de/allocate RAM?

I used to program in C/C++ and I'm struggling a bit to understand the automatisms of Rust :stuck_out_tongue:
I tried searching for ~1h in Google but I'm either stuck in a "Google bubble" or I'm using the wrong search terms or nobody asked this so far... (which I doubt) :stuck_out_tongue:

Maybe the Rust compiler is super-clever and even in case #1 the memory is not de&allocated during each loop? In my case the vector's size is unpredictable as its contents are loaded from a database... .

Thank you

The compiler can sometimes remove allocations, but I don't think it can usually re-use them. See https://github.com/rust-lang/rust/issues/93707 for an example of a case where hopefully it will be able to do it eventually, though it can't right now.

So yes, your second version that re-uses the buffer will avoid the extra (de)allocations, and is thus likely faster.

That said, allocators are often optimized for freeing and reallocating something of about the same size, since it's incredibly common. So if you're doing material work inside the loop, you might not even notice the difference. Assuming you're using a good allocator, of course, but if you're not sure you could always try a different one from a crate, like MiMalloc — Rust memory management library // Lib.rs or jemallocator — Rust memory management library // Lib.rs.

1 Like

I understand this as a confirmation that using my 2nd version (variable created outside the loop) would be better/safer, respectively, that doing so is not "stupid" in Rust.

Assuming you're using a good allocator...

Ah, I'm not doing anything fancy right now (it was just a general question), and I previously had with some software mixed experiences as well even with jemalloc, so in general I'd like not to depend on them too much and to handle as much as I can directly in my code :slight_smile:
Thanks a lot!! :smiley: :+1:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.