Added benchmarks + optimizations

As one redditor stated, I'm claiming that my program is fast without benchmarks. Here's said benchmark ;). The benchmarks use Criterion and just see how many magnet url's it can make per second. On the sluggish laptop I'm using at the moment, I get around 50K/s.

Removed redundant if statement in lib.rs for the tr field, increasing performance by 40%.

Made it so that the xl field uses a customized match statement for its output, basically making it so it converts from a str to an int, further increasing performance by 11%.
This commit is contained in:
William Batista 2021-02-17 16:44:36 -05:00
parent f2ae4d9be2
commit 0bef3c6e40
No known key found for this signature in database
GPG Key ID: C6D7973D216F38D3
3 changed files with 50 additions and 5 deletions

View File

@ -14,3 +14,20 @@ edition = "2018"
[dependencies]
lazy_static = "1"
regex = "1"
[dev-dependencies]
criterion = {version="0.3", features=["html_reports"]}
[[bench]]
name = "benchmark"
harness = false
[profile.bench]
opt-level = 3
lto = "fat"
codegen-units = 1
[profile.release]
opt-level = 3
lto = "fat"
codegen-units = 1

21
benches/benchmark.rs Normal file
View File

@ -0,0 +1,21 @@
use criterion::{criterion_group, criterion_main, Criterion, BenchmarkId, Throughput, black_box};
extern crate magnet_url;
use magnet_url::Magnet;
fn criterion_benchmark(c: &mut Criterion) {
let magnet = black_box("magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent");
let mut group = c.benchmark_group("sintel");
group.throughput(Throughput::Elements(1));
group.bench_with_input(BenchmarkId::new("sintel", magnet), &magnet, |b, &s| {
b.iter(|| Magnet::new(s));
});
group.finish();
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

View File

@ -97,6 +97,7 @@ const MANIFEST_TOPIC_RE_STR: &str = r"mt=((\w+)[A-Za-z0-9!@#$%^:*<>,?/()_+=.{}\\
/// use magnet_url::Magnet;
/// let _magnet_link = Magnet::new("https://example.com");
/// ```
pub struct Magnet {
///Display Name of the torrent
pub dn: String,
@ -169,16 +170,22 @@ impl Magnet {
dn: validate_regex(&DISPLAY_NAME_RE, 1),
hash_type: validate_regex(&EXACT_TOPIC_RE, 1),
xt: validate_regex(&EXACT_TOPIC_RE, 2),
xl: validate_regex(&EXACT_LENGTH_RE, 1).parse().unwrap_or(-1),
// Using a slightly modified match statement so it doesn't parse from str to String to int
xl: {
match &EXACT_LENGTH_RE.captures(magnet_str) {
Some(m) => m.get(1).map_or("-1", |m| m.as_str()).parse().unwrap_or(-1),
None => -1,
}
},
xs: validate_regex(&EXACT_SOURCE_RE, 1),
tr: {
let mut tr_vec: Vec<String> = Vec::new();
// Since tr is a vector, I can't just use the validate_regex function
if ADDRESS_TRACKER_RE.is_match(magnet_str) {
for tr in ADDRESS_TRACKER_RE.captures_iter(magnet_str) {
tr_vec.push(tr.get(1).map_or("", |m| m.as_str()).to_string());
}
for tr in ADDRESS_TRACKER_RE.captures_iter(magnet_str) {
tr_vec.push(tr.get(1).map_or("", |m| m.as_str()).to_string());
}
tr_vec
},