I want to malloc an array in heap instead of using Vector.
This is a similar C code:
int *arr = (int *)malloc(sizeof(int) * array_size);
Is there a good way to malloc an array in heap in rust ?
I want to malloc an array in heap instead of using Vector.
This is a similar C code:
int *arr = (int *)malloc(sizeof(int) * array_size);
Is there a good way to malloc an array in heap in rust ?
Vec
uses the heap to store its values. You could use a Box
with an array, e.g. Box<[u8; 32]>
I don't want use the heap in Vec as you say. I would rather use my own heap array which is malloced by myself.
But why. There's no need to reinvent the wheel.
If you want a growable array, use Vec
, period! If you want a fixed size array, use [type; size]
(e.g. [u8; 16]
). If you want it on the heap use Box
.
Because I want to test a vector production performance. I want to see which is better in C++ and rust. So I don't need any other data or operation which affects the result.
If I use Vec to test vector production in Rust, it is 1/3 slower than C++.
Have you used --release
to compile your program?
Yes, of course. I compare Rust using --release and C++ using -O3
Please show the Rust code you are using, compared to the C++ one. I bet we can find something that can be optimized.
What's more, the assembly code which objdump -d from binary file compiled by cargo/rustc is 30000+ lines, while 500+ lines in C/C++.
Here is Rust and C++ code. Any help will be appreciated!
use std::io;
use std::time::{Duration, Instant};
use std::alloc::{alloc, dealloc, Layout};
fn mymalloc(size: usize) -> Box<[i32]> {
(vec![0; size]).into_boxed_slice()
}
fn main() {
let mut v1 = mymalloc(100_000_000);
let mut v2 = mymalloc(100_000_000);
let mut vsum = mymalloc(100_000_000);
for i in 0..100_000_000 {
v1[i]= (i + 2) as i32;
v2[i] = (i - 1) as i32;
}
let now = Instant::now();
for k in 0..1_000 {
for i in 0..100_000_000 {
vsum[i] += v1[i] * v2[i];
}
}
println!("time = {}", now.elapsed().as_millis());
// assert_eq!(vsum[10000], 10002 * 9999);
}
#include <stdio.h>
#include <time.h>
#include <vector>
#include <stdlib.h>
using std::vector;
int main() {
auto a = vector<int>(100000000);
auto b = vector<int>(100000000);
auto c = vector<int>(100000000);
for (int i = 0; i < 100000000; ++i) {
a[i] = i + 2;
b[i] = i - 1;
}
struct timespec tm, ts;
clock_gettime(CLOCK_MONOTONIC, &tm);
for (int k = 0; k < 1000; ++k)
for (int i = 0; i < 100000000; ++i) {
c[i] += a[i] * b[i];
}
clock_gettime(CLOCK_MONOTONIC, &ts);
printf("time = %lf\n", (ts.tv_sec - tm.tv_sec) + (ts.tv_nsec - tm.tv_nsec)*1E-9);
return 0;
}
Funny enough, replacing the Box<[i32]>
with Vec<i32>
decreased the time by 20s for me. It now outperforms C++ (I haven't changed anything else).
Rust: 80212
C++ : 82470
I don't see the problem you described.
In my machine (CPU: intel i5-9600K), the time of C++ is 59720 ms.
If I using Vec<i32>, the time of Rust is 82812 ms.
If I using Box<[i32]>, the time of Rust is 80763 ms.
I think I figure out it why Rust is slower. I use Vec::with_capacity(100_000_000) and vsum.resize(100_000_000, 0) to resize vsum vector. When I change to vec![0; 100_000_000], it is just a bit slower than C++( spend 2s more than C++). So can you explain why ?
I used vec![0; size]
to create a Vec
. That's what I meant, when I changed to replace Box
by Vec
. Sorry, I think I wasn't clear enough.
I think I've got a funny situation again..
use std::time::{Instant};
fn main() {
let mut v1 = vec![0; 100_000_000];
let mut v2 = vec![0; 100_000_000];
let mut vsum = vec![0; 100_000_000];
for i in 0..100_000_000 {
v1[i] = (i + 2) as i32;
v2[i] = (i - 1) as i32;
}
let now = Instant::now();
for _ in 0..1_000 {
for i in 0..100_000_000 {
vsum[i] += v1[i] * v2[i];
}
}
println!("time = {}", now.elapsed().as_millis());
// assert_eq!(vsum[10000], 10002 * 9999);
}
The the performance of code above is good, just 2s slower than C++.
But if I add two statements to make v1, v2 immutable like this:
use std::time::{Instant};
fn main() {
let mut v1 = vec![0; 100_000_000];
let mut v2 = vec![0; 100_000_000];
let mut vsum = vec![0; 100_000_000];
for i in 0..100_000_000 {
v1[i] = (i + 2) as i32;
v2[i] = (i - 1) as i32;
}
let v1 = v1;
let v2 = v2;
let now = Instant::now();
for _ in 0..1_000 {
for i in 0..100_000_000 {
vsum[i] += v1[i] * v2[i];
}
}
println!("time = {}", now.elapsed().as_millis());
// assert_eq!(vsum[10000], 10002 * 9999);
}
It is 10s slower than C++.
You should start formatting your code by using rustfmt
(rustup component add rustfmt
and then you can do cargo fmt
).
Next, please replace 100_000_000
by a constant. It's a pain to see that large number over and over again and squeeze my eyes to see if they are actually equal to each other.
It made it actually 6 seconds faster than C++. I had to ask this earlier, but which version of rust are you using? (rustc --version
)
rustc 1.34.1 (fc50f328b 2019-04-24)
gcc (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0
Which version of your C++ compiler you are using?