Skip to content

Commit e409ce5

Browse files
dmitryikhdmitry.khominich
authored and
dmitry.khominich
committed
initial
0 parents  commit e409ce5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1745
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.swp

README.md

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# C++11 vs Rust comparison
2+
3+
## Intro
4+
5+
The goal of this project is to understand programming idioms of Rust, and
6+
roughly measure Rust performance compared to C++11. For this purpose several
7+
well known algorithmic problems were considered. The problems were inspired and
8+
evolved from great computer science course "Algorithms: Theory & Practice" on
9+
Stepik paltform. Here the link to the course:
10+
https://stepik.org/course/217/syllabus .
11+
12+
## Problems
13+
14+
Here is short overview of the programming problems considered in the project.
15+
More detailed description of each task could be found in the tasks' folders.
16+
17+
`huffman_encoding` and `huffman_decoding` are about of building optimal prefix
18+
code for the given message and decoding it back. These problems are about to
19+
work with priority queque (heap data structure), binary tree and hash map.
20+
Particular realisations on Rust and C++11 relies on standard libraries'
21+
realisation of hash map and priority queue implementing only binary tree to
22+
solve the problem. Complexity is O(N) for building the code.
23+
24+
`binary_search` is quite well known and straightforward algorithm for searching
25+
of the particular value in a sorted array. Here is no significant distinctions
26+
in realisations. Complexity is O(logN).
27+
28+
`mergesort` algorithm of sorting is implemented in non-recursion way in order
29+
to avoid stack overflow. Complexity is O(N logN).
30+
31+
`levenshtein` distance is usually used to quantify the difference between two
32+
strings. The algorithm is implemented in dynamic prgramming manner. Complexity is O(N^2).
33+
34+
## Folders overview
35+
36+
Each problem can be found in the folder with the same name. In each folder here
37+
are `main.cpp` and `main.rs` source codes which is solving the described
38+
problems in C++11 and Rust. Also here is `Makefile` in each folder to compile
39+
the programs, prepare test data and perform performance measures. The common
40+
part of the `Makefile` can be found in `common/common.make`.
41+
42+
Also each problem's folder contains `generator` project on Rust which is
43+
dedicated to generate input data for prgrams for testing purposes.
44+
45+
Although one can find brief overview of the problems above, in the particular
46+
folder here is `README.md` with more formal problem descriptions and notes.
47+
48+
## Performance testing set up
49+
50+
Each problem has Make scenario with 4 rules: `main_rust`, `main_cpp`, `gen` and
51+
`bench`. First two are about compiling the programs. Every program recieves its
52+
input on `stdin` and write results in `stdout`. `gen` will prepare test data:
53+
three input sets `inp_low`, `inp_mid`, `inp_hi` with increasing problem sizes.
54+
Generally, `inp_low` contains smallest inputs, and `inp_hi` contains millions
55+
of entities and it usually takes few seconds to solve the problem of a such size.
56+
`bench` rule will call `common/compare_performace.sh` which will perform N (N =
57+
10) runs of every input on evety program and everage the result. Occasianally,
58+
here is not standard command line tool for measure the program runtime in
59+
milisecond resolution for Mac Os X and Linux.. Therefore in `common/measure`
60+
you will find a small rust program to meausre the runtime of another program.
61+
To run all steps in once, one can use `run_bench.sh`. It will take up to ten
62+
minutes to perform all compilations, generations and performance measures.
63+
64+
## Compilation
65+
66+
The next command line is used to compile C++ program:
67+
68+
```
69+
g++ -std=c++11 -O2 -o main_cpp main.cpp
70+
```
71+
72+
The next command line is used to compile Rust program:
73+
74+
```
75+
rustc -O --crate-name main_rust main.rs
76+
```
77+
78+
79+
## Requirements
80+
81+
One needs to run Mac Os X or Linux with installed to PATH GNU C++ compiler or Clang and Rust. By the author the presented project was tested with the next softwares:
82+
83+
```
84+
> rustc -V
85+
Rustc 1.20.0 (f3d6973f4 2017-08-27)
86+
87+
> g++ -v
88+
...
89+
gcc version 7.2.0
90+
```
91+
92+
## License
93+
94+
Actually here is no any type of restrictions on the materials in this repository. Anyone can do anything with the source code and results.

benchmark_results_raw.md

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
The test was launched by `run_bench.sh` script. The testing hardware is: Intel Core i7-4770, 16GB DDR3, SSD, Linux Mint 18.1 64-bit.
2+
The output:
3+
```
4+
Test 4_2_5
5+
6+
Compiling programs..
7+
Generate test data..
8+
Measuring performance..
9+
../common/compare_performance.sh
10+
Averaging performance of 10 runs..
11+
./main_cpp:
12+
test inp_low: .00168 sec
13+
test inp_mid: .02829 sec
14+
test inp_hi: .27003 sec
15+
16+
./main_rust:
17+
test inp_low: .00169 sec
18+
test inp_mid: .04197 sec
19+
test inp_hi: .43336 sec
20+
21+
Test 4_2_6
22+
23+
Compiling programs..
24+
Generate test data..
25+
Measuring performance..
26+
../common/compare_performance.sh
27+
Averaging performance of 10 runs..
28+
./main_cpp:
29+
test inp_low: .00185 sec
30+
test inp_mid: .04698 sec
31+
test inp_hi: .43825 sec
32+
33+
./main_rust:
34+
test inp_low: .00152 sec
35+
test inp_mid: .02622 sec
36+
test inp_hi: .24990 sec
37+
38+
Test 6_1_4
39+
40+
Compiling programs..
41+
Generate test data..
42+
Measuring performance..
43+
../common/compare_performance.sh
44+
Averaging performance of 10 runs..
45+
./main_cpp:
46+
test inp_low: .00288 sec
47+
test inp_mid: .15820 sec
48+
test inp_hi: 1.85318 sec
49+
50+
./main_rust:
51+
test inp_low: .00223 sec
52+
test inp_mid: .12787 sec
53+
test inp_hi: 1.55638 sec
54+
55+
Test 6_4_5
56+
57+
Compiling programs..
58+
Generate test data..
59+
Measuring performance..
60+
../common/compare_performance.sh
61+
Averaging performance of 10 runs..
62+
./main_cpp:
63+
test inp_low: .00312 sec
64+
test inp_mid: .19478 sec
65+
test inp_hi: 2.10201 sec
66+
67+
./main_rust:
68+
test inp_low: .00254 sec
69+
test inp_mid: .15996 sec
70+
test inp_hi: 1.83357 sec
71+
72+
Test 8_3_8
73+
74+
Compiling programs..
75+
Generate test data..
76+
Measuring performance..
77+
../common/compare_performance.sh
78+
Averaging performance of 10 runs..
79+
./main_cpp:
80+
test inp_low: .00405 sec
81+
test inp_mid: .01352 sec
82+
test inp_hi: .04957 sec
83+
84+
./main_rust:
85+
test inp_low: .00410 sec
86+
test inp_mid: .01416 sec
87+
test inp_hi: .05289 sec
88+
```

binary_search/Makefile

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
include ../common/common.make
2+
3+
gen:
4+
cd ./generator;\
5+
echo "10000 1000 0.5" | cargo run > ../inp_low;\
6+
echo "1000000 100000 0.5" | cargo run > ../inp_mid;\
7+
echo "10000000 1000000 0.5" | cargo run > ../inp_hi;\
8+
cd ..

binary_search/README.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Binary search
2+
3+
## Problem description
4+
5+
For the given arrays `A` and `B` print index `j` that is `A[j] = B[i]` for
6+
every `i`, or `-1` if `B[i]` is not found in the `A`. The first line contains
7+
`n`, which is number of elements in `A`. And `n` integer numbers, which is
8+
`A`'s elements. The second line containes the same information for `B` array.
9+
10+
```
11+
Sample Input:
12+
5 1 5 8 12 13
13+
5 8 1 23 1 11
14+
15+
Sample Output:
16+
3 1 -1 1 -1
17+
```
18+
19+
The original problem was taken form: https://stepik.org/lesson/13246/step/4
20+
21+
## Note
22+
23+
If A contains several elements with the same value, we should find any of them.

binary_search/generator/Cargo.lock

+64
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

binary_search/generator/Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "generator"
3+
version = "0.1.0"
4+
authors = ["Dmitry Khominich"]
5+
6+
[dependencies]
7+
rand = "*"

binary_search/generator/src/main.rs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
extern crate rand;
2+
use std::io;
3+
use rand::Rng;
4+
5+
6+
fn read_line() -> String {
7+
let mut line = String::new();
8+
io::stdin().read_line(&mut line).unwrap();
9+
line.trim().to_string()
10+
}
11+
12+
fn main() {
13+
let line = read_line();
14+
let mut iter = line.split_whitespace();
15+
// A size
16+
let n: usize = iter.next().unwrap().parse().unwrap();
17+
// B size
18+
let k: usize = iter.next().unwrap().parse().unwrap();
19+
// Uniform probabily that B[i] is in A
20+
let pr: f64 = iter.next().unwrap().parse().unwrap();
21+
22+
let mut a_vec: Vec<u32> = vec![0; n];
23+
let mut b_vec: Vec<u32> = vec![0; k];
24+
for a in &mut a_vec {
25+
*a = rand::thread_rng().gen_range(1, 1_000_000_000);
26+
}
27+
for b in &mut b_vec {
28+
let chance: f64 = rand::thread_rng().gen_range(0.0, 1.0);
29+
*b = if chance <= pr {
30+
a_vec[rand::thread_rng().gen_range(0, n)]
31+
} else {
32+
rand::thread_rng().gen_range(1, 1_000_000_000)
33+
}
34+
}
35+
print!("{}", n);
36+
for a in a_vec {
37+
print!(" {}", a);
38+
}
39+
println!("");
40+
41+
print!("{}", k);
42+
for b in b_vec {
43+
print!(" {}", b);
44+
}
45+
println!("");
46+
}

binary_search/main.cpp

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include <cassert>
2+
#include <iostream>
3+
#include <vector>
4+
#include <algorithm>
5+
6+
// return position of the element if found (indexing from 1),
7+
// return -1 otherwise
8+
template<typename T>
9+
int binary_search(std::vector<T> const& vec, T const& value) {
10+
int l = 0;
11+
int r = static_cast<int>(vec.size() - 1);
12+
int i;
13+
while(l <= r) {
14+
i = int((l + r) / 2);
15+
if(vec[i] == value) {
16+
return i + 1;
17+
} else if(vec[i] > value) {
18+
r = i - 1;
19+
} else if(vec[i] < value) {
20+
l = i + 1;
21+
}
22+
}
23+
return -1;
24+
}
25+
26+
// read number of elements, read elements into vector
27+
std::vector<int> read_vec_w_num() {
28+
size_t n;
29+
std::cin >> n;
30+
std::vector<int> vec(n, 0);
31+
for (auto& val: vec)
32+
std::cin >> val;
33+
return vec;
34+
}
35+
36+
int main(int argc, char** argv) {
37+
std::ios::sync_with_stdio(false);
38+
39+
// 1. Read the array, and values for search
40+
auto a_vec = read_vec_w_num();
41+
auto const b_vec = read_vec_w_num();
42+
43+
// 2. Sort the array
44+
std::sort(std::begin(a_vec), std::end(a_vec));
45+
46+
// 3. Search values, write results
47+
for (auto const& val: b_vec)
48+
std::cout << binary_search(a_vec, val) << " ";
49+
50+
return 0;
51+
}
52+

0 commit comments

Comments
 (0)