Re: The Case for Rust (in any system)

From: Jason Bacon <bacon4000_at_gmail.com>
Date: Fri, 13 Sep 2024 19:43:44 UTC
On 9/13/24 08:21, Alan Somers wrote:
> On Fri, Sep 13, 2024 at 7:15 AM Jason Bacon <bacon4000@gmail.com> wrote:
>>
>> On 9/13/24 05:33, Paul Floyd wrote:
>>>
>>>
>>> On 13-09-24 06:17, David Chisnall wrote:
>>>> On 13 Sep 2024, at 02:34, Joe Schaefer <joesuf4@gmail.com> wrote:
>>>>>
>>>>> I just completed a month long project to port a C++ codebase that
>>>>> used vectors for array allocations back to using C‘s calloc. For a
>>>>> 15% increase in memory footprint, batch jobs that took three days to
>>>>> complete now finish in 10-12 hours.
>>>>
>>>> This sounds highly dubious given that std::vector is a very thin
>>>> wrapper around malloc. From your description, I would expect the same
>>>> speedup with some judicial use of .reserve().
>>>
>>> I was going to say exactly the same thing.
>>>
>>> Considering the reply to this, another one to be plonked so that I waste
>>> less time.
>>>
>>> A+
>>> Paul
>>>
>>>
>>>
>>
>> Some years ago, I wrote a script to time a simple selection sort coded
>> in various languages.  Here's an example of the results:
>>
>> https://github.com/outpaddling/Lang-speed/blob/master/Results/coral-amd64-100000
>>
>> Note: The clang array/pointer performance is currently regressed due to
>> changes in the optimization parameters since clang 8.  That's why it's
>> noticeably slower than GCC in these results.
>>
>> https://github.com/llvm/llvm-project/issues/53205#issuecomment-2318697322
>>
>> In general, I have not seen a significant difference between arrays and
>> vectors in all my years running this benchmark.
>>
>> This benchmark is anecdotal, as it only measures performance for one
>> algorithm.  But in my experience, C++ shows marginally slower
>> performance and noticeably more memory use than C.
>>
>> Coming back to Rust: The results above, showing about double the runtime
>> of C and C++, is the best I've seen from it.  It was taking 4x as long
>> as C/C++ a few years ago.  That's one reason I don't use it.  I do
>> mostly scientific computing, where runtime can be costly.  This is not
>> *always* an issue in systems code, but it should be examined before
>> choosing a language for a particular implementation.  The other reason
>> is the impact of a Rust dependency on FreeBSD ports and pkgsrc packages:
>> Frequent changes to the Rust port/package lead to long build times and
>> frequent breakage of dependents.
> 
> Right away, I can see that while your C program mallocs the array to
> the list's full size, your Rust program doesn't.  It grows the list
> one element at a time, with Vec::push .  I bet that if you change the
> Rust program to use Vec::reserve or Vec::with_capacity, so that it
> only has to allocate once, you'll find the results are different.
> -Alan

Thanks for the tip.  I assume this is what you meant:

--- a/selsort.rs
+++ b/selsort.rs
@@ -19,7 +19,8 @@ fn read_list(list: &mut Vec<i32>)
      io::stdin().read_line(&mut str).expect("failed to read input.");
      let list_size: usize = str.trim().parse().expect("invalid input");
      println!("list_size = {:?}", list_size);
+    list.reserve(list_size);
      for _c in 0..list_size
      {
         let mut str = String::new();

It had no noticeable effect on runtime.  Not too surprising, as the vast 
majority of the runtime is in the O(N^2) selection_sort() function 
rather than the O(N) read_list().  I'd also be shocked if Vec::push() 
actually allocated 1 integer at a time.

-- 
Life is a game.  Play hard.  Play fair.  Have fun.