Skip to content

Commit c6dcf38

Browse files
committed
simplify this project (by removing the complex but useless "vec" usage), improve the patterns
1 parent eda2ff2 commit c6dcf38

File tree

10 files changed

+792
-1566
lines changed

10 files changed

+792
-1566
lines changed

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[package]
22
name = "lazy-static-include"
3-
version = "2.3.0"
3+
version = "3.0.0"
44
authors = ["Magic Len <len@magiclen.org>"]
55
edition = "2018"
66
repository = "https://github.com/magiclen/lazy-static-include"
77
homepage = "https://magiclen.org/lazy-static-include"
88
keywords = ["lazy", "macro", "static", "include"]
99
categories = ["memory-management", "rust-patterns"]
10-
description= "This crate provides `lazy_static_include_bytes` and `lazy_static_include_str` macros to replace `include_bytes` and `include_str` macros."
10+
description = "This crate provides `lazy_static_include_bytes` and `lazy_static_include_str` macros to replace `include_bytes` and `include_str` macros."
1111
readme = "README.md"
1212
license = "MIT"
1313
include = ["src/**/*", "Cargo.toml", "benches/bench.rs"]
@@ -18,8 +18,8 @@ branch = "master"
1818

1919
[dependencies]
2020
lazy_static = "1.4"
21-
syn = {version = "1", features = ["full"]}
22-
starts-ends-with-caseless = "0.5"
21+
slash-formatter = "3"
22+
syn = { version = "1", features = ["full"] }
2323

2424
[dev-dependencies]
2525
bencher = "0.1.5"

README.md

Lines changed: 46 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -21,47 +21,49 @@ The paths used for `lazy_static_include_bytes` and `lazy_static_include_str` are
2121

2222
```rust
2323
#[macro_use] extern crate lazy_static_include;
24-
#[macro_use] extern crate lazy_static;
2524

26-
lazy_static_include_str!(TEST, "data/test.txt");
27-
lazy_static_include_str!(pub TEST2, "data/test-2.txt");
25+
lazy_static_include_str! {
26+
/// doc
27+
TEST => "data/test.txt",
28+
/// doc
29+
pub TEST2 => "data/test-2.txt",
30+
}
2831

2932
assert_eq!("This is just a test text.", TEST);
3033
assert_eq!(TEST2, "Some text...");
3134
```
3235

3336
```rust
3437
#[macro_use] extern crate lazy_static_include;
35-
#[macro_use] extern crate lazy_static;
3638

37-
lazy_static_include_bytes!(TEST, "data/test.txt", "data/test-2.txt");
39+
lazy_static_include_bytes! {
40+
/// doc
41+
TEST => "data/test.txt",
42+
/// doc
43+
pub TEST2 => "data/test-2.txt",
44+
}
3845

39-
assert_eq!("This is just a test text.".as_bytes(), TEST[0]);
40-
assert_eq!(TEST[1], "Some text...".as_bytes());
46+
assert_eq!(b"This is just a test text.".as_ref(), TEST);
47+
assert_eq!(TEST2, b"Some text...".as_ref());
4148
```
4249

43-
You should notice that the struct created from `lazy_static_include_bytes` and `lazy_static_include_str` macros isn't equal to `&'static [u8]` or `&'static str`.
44-
If you want to get an exact `&'static [u8]` or `&'static str` reference, you need to **dereference the struct**.
50+
You should notice that the value created from `lazy_static_include_bytes` and `lazy_static_include_str` macros isn't equal to `&'static [u8]` or `&'static str` when you are not using the **release** profile. If you want to get an exact `&'static [u8]` or `&'static str` reference, you can **dereference** the value or just use the `as_ref` method.
4551

4652
```rust
4753
#[macro_use] extern crate lazy_static_include;
48-
#[macro_use] extern crate lazy_static;
4954

50-
lazy_static_include_bytes!(TEST, "data/test.txt");
55+
lazy_static_include_bytes! {
56+
/// doc
57+
TEST => "data/test.txt",
58+
}
5159

60+
#[cfg(debug_assertions)]
5261
let data: &'static [u8] = *TEST;
53-
```
54-
55-
If you include str and bytes from multiple files, after dereferencing the struct, you will get a `Vec<&'static [u8]>` or a `Vec<&'static str>`.
56-
In order to not move out of borrowed content, use **&*** to get the reference of that `Vec`.
57-
58-
```rust
59-
#[macro_use] extern crate lazy_static_include;
60-
#[macro_use] extern crate lazy_static;
6162

62-
lazy_static_include_str!(TEST, "data/test.txt", "data/test-2.txt");
63+
#[cfg(not(debug_assertions))]
64+
let data: &'static [u8] = TEST;
6365

64-
let v: &Vec<&'static str> = &*TEST;
66+
let data: &'static [u8] = TEST.as_ref();
6567
```
6668

6769
## Include Array
@@ -72,64 +74,46 @@ The array is fixed sized and can be one of these following types: `bool`, `char`
7274
Also, the `lazy_static_include_array` macro includes data from files into the compiled executable binary file **only** when you are using the **release** profile.
7375
Be careful when you distribute your program.
7476

77+
The paths used for `lazy_static_include_array` are relative to **CARGO_MANIFEST_DIR**.
78+
7579
```rust
7680
#[macro_use] extern crate lazy_static_include;
77-
#[macro_use] extern crate lazy_static;
7881

79-
lazy_static_include_array!(TEST: [u64; 5], "data/u64_array.txt");
82+
lazy_static_include_array! {
83+
/// doc
84+
TEST: [u64; 5] => "data/u64_array.txt",
85+
/// doc
86+
pub TEST2: [&'static str; 3] => "data/string_array.txt"
87+
}
88+
8089
assert_eq!(123, TEST[0]);
8190
assert_eq!(456, TEST[1]);
8291
assert_eq!(789, TEST[2]);
8392
assert_eq!(1000, TEST[3]);
8493
assert_eq!(500000000000u64, TEST[4]);
85-
```
86-
87-
```rust
88-
#[macro_use] extern crate lazy_static_include;
89-
#[macro_use] extern crate lazy_static;
90-
91-
lazy_static_include_array!(TEST: [i32; 5], "data/i32_array.txt", "data/i32_array-2.txt");
92-
assert_eq!(123, TEST[0][0]);
93-
assert_eq!(-456, TEST[0][1]);
94-
assert_eq!(789, TEST[0][2]);
95-
assert_eq!(1000, TEST[0][3]);
96-
assert_eq!(5000, TEST[0][4]);
97-
98-
assert_eq!(-1, TEST[1][0]);
99-
assert_eq!(-2, TEST[1][1]);
100-
assert_eq!(-3, TEST[1][2]);
101-
assert_eq!(-4, TEST[1][3]);
102-
assert_eq!(-5, TEST[1][4]);
103-
```
104-
105-
```rust
106-
#[macro_use] extern crate lazy_static_include;
107-
#[macro_use] extern crate lazy_static;
108-
109-
lazy_static_include_array!(pub TEST: [&'static str; 3], "data/string_array.txt");
11094

111-
assert_eq!("Hi", TEST[0]);
112-
assert_eq!("Hello", TEST[1]);
113-
assert_eq!("哈囉", TEST[2]);
95+
assert_eq!("Hi", TEST2[0]);
96+
assert_eq!("Hello", TEST2[1]);
97+
assert_eq!("哈囉", TEST2[2]);
11498
```
11599

116100
## Benchmark
117101

118-
Using static mechanisms makes your program faster. See my benchmark result below (Intel i7-6700HQ, ran on 2019/07/16):
102+
Using static mechanisms makes your program faster. See my benchmark result below (AMD Ryzen 9 3900X 12-Core Processor 12C/24T 3.90GHz, ran on 2020/07/02):
119103

120104
```text
121-
test include_array_lazy_static ... bench: 43 ns/iter (+/- 3)
122-
test include_array_native_static ... bench: 46 ns/iter (+/- 4)
123-
test include_array_no_static ... bench: 29,714 ns/iter (+/- 1,156)
124-
test include_bytes_lazy_static ... bench: 382 ns/iter (+/- 63)
125-
test include_bytes_native_static ... bench: 380 ns/iter (+/- 30)
126-
test include_bytes_no_static ... bench: 9,076 ns/iter (+/- 1,224)
127-
test include_str_lazy_static ... bench: 932 ns/iter (+/- 103)
128-
test include_str_native_static ... bench: 937 ns/iter (+/- 25)
129-
test include_str_no_static ... bench: 10,135 ns/iter (+/- 1,634)
105+
test include_array_lazy_static ... bench: 45 ns/iter (+/- 3)
106+
test include_array_native_static ... bench: 45 ns/iter (+/- 3)
107+
test include_array_no_static ... bench: 20,959 ns/iter (+/- 295)
108+
test include_bytes_lazy_static ... bench: 754 ns/iter (+/- 7)
109+
test include_bytes_native_static ... bench: 755 ns/iter (+/- 11)
110+
test include_bytes_no_static ... bench: 4,560 ns/iter (+/- 179)
111+
test include_str_lazy_static ... bench: 753 ns/iter (+/- 10)
112+
test include_str_native_static ... bench: 755 ns/iter (+/- 7)
113+
test include_str_no_static ... bench: 4,830 ns/iter (+/- 198)
130114
```
131115

132-
When using the **release** profile, the performance of `lazy_static_include_*` is very close to `include_*`. That means you don't need to worry about the overhead, but just enjoy the faster compilation time.
116+
When using the **release** profile, the performance of `lazy_static_include_*` is very close to `include_*` (in fast, they are the same). That means you don't need to worry about the overhead, but just enjoy the faster compilation time.
133117

134118
You can run the benchmark program by executing,
135119

benches/bench.rs

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,77 +4,92 @@ extern crate bencher;
44
#[macro_use]
55
extern crate lazy_static_include;
66

7+
#[macro_use]
8+
extern crate slash_formatter;
9+
710
extern crate serde_json;
811

912
use std::fs::File;
1013
use std::io::Read;
14+
use std::str::from_utf8_unchecked;
1115

1216
use bencher::Bencher;
1317

14-
fn include_str_no_static(bencher: &mut Bencher) {
15-
let path = concat!(concat!(env!("CARGO_MANIFEST_DIR"), "/", "data/benchmark.txt"));
18+
macro_rules! benchmark_text_path {
19+
() => {
20+
concat_with_file_separator!(env!("CARGO_MANIFEST_DIR"), "data", "benchmark.txt")
21+
};
22+
(relative) => {
23+
concat_with_file_separator!("data", "benchmark.txt")
24+
};
25+
}
1626

27+
fn include_str_no_static(bencher: &mut Bencher) {
1728
bencher.iter(|| {
18-
let mut f = File::open(&path).unwrap();
29+
let mut f = File::open(benchmark_text_path!()).unwrap();
1930

2031
let mut v = Vec::new();
2132

2233
f.read_to_end(&mut v).unwrap();
2334

2435
let s = String::from_utf8(v).unwrap();
2536

26-
assert!(s.contains("figarofigaro"));
37+
s.contains("figarofigaro")
2738
});
2839
}
2940

3041
fn include_str_native_static(bencher: &mut Bencher) {
31-
let text = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/", "data/benchmark.txt"));
42+
let text = include_str!(benchmark_text_path!());
3243

33-
bencher.iter(|| {
34-
assert!(text.contains("figarofigaro"));
35-
});
44+
bencher.iter(|| text.contains("figarofigaro"));
3645
}
3746

3847
fn include_str_lazy_static(bencher: &mut Bencher) {
39-
lazy_static_include_str!(TEXT, "data/benchmark.txt");
48+
lazy_static_include_str! {
49+
pub TEXT => benchmark_text_path!(relative)
50+
}
4051

41-
bencher.iter(|| {
42-
assert!((*TEXT).contains("figarofigaro"));
43-
});
52+
bencher.iter(|| TEXT.contains("figarofigaro"));
4453
}
4554

4655
fn include_bytes_no_static(bencher: &mut Bencher) {
47-
let path = concat!(concat!(env!("CARGO_MANIFEST_DIR"), "/", "data/benchmark.txt"));
48-
4956
bencher.iter(|| {
50-
let mut f = File::open(&path).unwrap();
57+
let mut f = File::open(benchmark_text_path!()).unwrap();
5158

5259
let mut v = Vec::new();
5360

5461
f.read_to_end(&mut v).unwrap();
5562

56-
String::from_utf8(v).unwrap();
63+
let text = unsafe { from_utf8_unchecked(&v) };
64+
65+
text.contains("figarofigaro")
5766
});
5867
}
5968

6069
fn include_bytes_native_static(bencher: &mut Bencher) {
61-
let data = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/", "data/benchmark.txt"));
70+
let data = include_bytes!(benchmark_text_path!());
6271

6372
bencher.iter(|| {
64-
String::from_utf8(data.to_vec()).unwrap();
73+
let text = unsafe { from_utf8_unchecked(data) };
74+
75+
text.contains("figarofigaro")
6576
});
6677
}
6778

6879
fn include_bytes_lazy_static(bencher: &mut Bencher) {
69-
lazy_static_include_bytes!(DATA, "data/benchmark.txt");
80+
lazy_static_include_bytes! {
81+
DATA => benchmark_text_path!(relative)
82+
}
7083

7184
bencher.iter(|| {
72-
String::from_utf8((*DATA).to_vec()).unwrap();
85+
let text = unsafe { from_utf8_unchecked(&DATA) };
86+
87+
text.contains("figarofigaro")
7388
});
7489
}
7590

7691
fn include_array_no_static(bencher: &mut Bencher) {
77-
let path = concat!(concat!(env!("CARGO_MANIFEST_DIR"), "/", "data/benchmark.txt"));
92+
let path = concat!(benchmark_text_path!());
7893

7994
bencher.iter(|| {
8095
let mut f = File::open(&path).unwrap();
@@ -85,24 +100,22 @@ fn include_array_no_static(bencher: &mut Bencher) {
85100

86101
let array: Vec<&str> = serde_json::from_slice(&v).unwrap();
87102

88-
assert!(array.binary_search(&"figarofigaro").is_ok());
103+
array.binary_search(&"figarofigaro").is_ok()
89104
});
90105
}
91106

92107
fn include_array_native_static(bencher: &mut Bencher) {
93-
let array = include!(concat!(env!("CARGO_MANIFEST_DIR"), "/", "data/benchmark.txt"));
108+
let array = include!(benchmark_text_path!());
94109

95-
bencher.iter(|| {
96-
assert!(array.binary_search(&"figarofigaro").is_ok());
97-
});
110+
bencher.iter(|| array.binary_search(&"figarofigaro").is_ok());
98111
}
99112

100113
fn include_array_lazy_static(bencher: &mut Bencher) {
101-
lazy_static_include_array!(ARRAY: [&'static str; 622], "data/benchmark.txt");
114+
lazy_static_include_array! {
115+
ARRAY: [&'static str; 622] => benchmark_text_path!(relative)
116+
}
102117

103-
bencher.iter(|| {
104-
assert!((*ARRAY).binary_search(&"figarofigaro").is_ok());
105-
});
118+
bencher.iter(|| ARRAY.binary_search(&"figarofigaro").is_ok());
106119
}
107120

108121
benchmark_group!(

0 commit comments

Comments
 (0)