]> git.proxmox.com Git - rustc.git/blob - vendor/csv/benches/bench.rs
New upstream version 1.72.1+dfsg1
[rustc.git] / vendor / csv / benches / bench.rs
1 #![feature(test)]
2
3 extern crate test;
4
5 use std::io;
6
7 use serde::{de::DeserializeOwned, Deserialize, Serialize};
8 use test::Bencher;
9
10 use csv::{
11 ByteRecord, Reader, ReaderBuilder, StringRecord, Trim, Writer,
12 WriterBuilder,
13 };
14
15 static NFL: &'static str = include_str!("../examples/data/bench/nfl.csv");
16 static GAME: &'static str = include_str!("../examples/data/bench/game.csv");
17 static POP: &'static str =
18 include_str!("../examples/data/bench/worldcitiespop.csv");
19 static MBTA: &'static str =
20 include_str!("../examples/data/bench/gtfs-mbta-stop-times.csv");
21
22 #[derive(Debug, Serialize, Deserialize, PartialEq)]
23 struct NFLRowOwned {
24 gameid: String,
25 qtr: i32,
26 min: Option<i32>,
27 sec: Option<i32>,
28 off: String,
29 def: String,
30 down: Option<i32>,
31 togo: Option<i32>,
32 ydline: Option<i32>,
33 description: String,
34 offscore: i32,
35 defscore: i32,
36 season: i32,
37 }
38
39 #[derive(Debug, Serialize, Deserialize, PartialEq)]
40 struct NFLRowBorrowed<'a> {
41 gameid: &'a str,
42 qtr: i32,
43 min: Option<i32>,
44 sec: Option<i32>,
45 off: &'a str,
46 def: &'a str,
47 down: Option<i32>,
48 togo: Option<i32>,
49 ydline: Option<i32>,
50 description: &'a str,
51 offscore: i32,
52 defscore: i32,
53 season: i32,
54 }
55
56 #[derive(Debug, Serialize, Deserialize, PartialEq)]
57 struct GAMERowOwned(String, String, String, String, i32, String);
58
59 #[derive(Debug, Serialize, Deserialize, PartialEq)]
60 struct GAMERowBorrowed<'a>(&'a str, &'a str, &'a str, &'a str, i32, &'a str);
61
62 #[derive(Debug, Serialize, Deserialize, PartialEq)]
63 #[serde(rename_all = "PascalCase")]
64 struct POPRowOwned {
65 country: String,
66 city: String,
67 accent_city: String,
68 region: String,
69 population: Option<i32>,
70 latitude: f64,
71 longitude: f64,
72 }
73
74 #[derive(Debug, Serialize, Deserialize, PartialEq)]
75 #[serde(rename_all = "PascalCase")]
76 struct POPRowBorrowed<'a> {
77 country: &'a str,
78 city: &'a str,
79 accent_city: &'a str,
80 region: &'a str,
81 population: Option<i32>,
82 latitude: f64,
83 longitude: f64,
84 }
85
86 #[derive(Debug, Serialize, Deserialize, PartialEq)]
87 struct MBTARowOwned {
88 trip_id: String,
89 arrival_time: String,
90 departure_time: String,
91 stop_id: String,
92 stop_sequence: i32,
93 stop_headsign: String,
94 pickup_type: i32,
95 drop_off_type: i32,
96 timepoint: i32,
97 }
98
99 #[derive(Debug, Serialize, Deserialize, PartialEq)]
100 struct MBTARowBorrowed<'a> {
101 trip_id: &'a str,
102 arrival_time: &'a str,
103 departure_time: &'a str,
104 stop_id: &'a str,
105 stop_sequence: i32,
106 stop_headsign: &'a str,
107 pickup_type: i32,
108 drop_off_type: i32,
109 timepoint: i32,
110 }
111
112 #[derive(Default)]
113 struct ByteCounter {
114 count: usize,
115 }
116 impl io::Write for ByteCounter {
117 fn write(&mut self, data: &[u8]) -> io::Result<usize> {
118 self.count += data.len();
119 Ok(data.len())
120 }
121 fn flush(&mut self) -> io::Result<()> {
122 Ok(())
123 }
124 }
125
126 macro_rules! bench {
127 ($name:ident, $data:ident, $counter:ident, $result:expr) => {
128 #[bench]
129 fn $name(b: &mut Bencher) {
130 let data = $data.as_bytes();
131 b.bytes = data.len() as u64;
132 b.iter(|| {
133 let mut rdr =
134 ReaderBuilder::new().has_headers(false).from_reader(data);
135 assert_eq!($counter(&mut rdr), $result);
136 })
137 }
138 };
139 }
140
141 macro_rules! bench_trimmed {
142 ($name:ident, $data:ident, $counter:ident, $result:expr) => {
143 #[bench]
144 fn $name(b: &mut Bencher) {
145 let data = $data.as_bytes();
146 b.bytes = data.len() as u64;
147 b.iter(|| {
148 let mut rdr = ReaderBuilder::new()
149 .has_headers(false)
150 .trim(Trim::All)
151 .from_reader(data);
152 assert_eq!($counter(&mut rdr), $result);
153 })
154 }
155 };
156 }
157
158 macro_rules! bench_serde {
159 (no_headers,
160 $name_de:ident, $name_ser:ident, $data:ident, $counter:ident, $type:ty, $result:expr) => {
161 #[bench]
162 fn $name_de(b: &mut Bencher) {
163 let data = $data.as_bytes();
164 b.bytes = data.len() as u64;
165 b.iter(|| {
166 let mut rdr =
167 ReaderBuilder::new().has_headers(false).from_reader(data);
168 assert_eq!($counter::<_, $type>(&mut rdr), $result);
169 })
170 }
171 #[bench]
172 fn $name_ser(b: &mut Bencher) {
173 let data = $data.as_bytes();
174 let values = ReaderBuilder::new()
175 .has_headers(false)
176 .from_reader(data)
177 .deserialize()
178 .collect::<Result<Vec<$type>, _>>()
179 .unwrap();
180
181 let do_it = || {
182 let mut counter = ByteCounter::default();
183 {
184 let mut wtr = WriterBuilder::new()
185 .has_headers(false)
186 .from_writer(&mut counter);
187 for val in &values {
188 wtr.serialize(val).unwrap();
189 }
190 }
191 counter.count
192 };
193 b.bytes = do_it() as u64;
194 b.iter(do_it)
195 }
196 };
197 ($name_de:ident, $name_ser:ident, $data:ident, $counter:ident, $type:ty, $result:expr) => {
198 #[bench]
199 fn $name_de(b: &mut Bencher) {
200 let data = $data.as_bytes();
201 b.bytes = data.len() as u64;
202 b.iter(|| {
203 let mut rdr =
204 ReaderBuilder::new().has_headers(true).from_reader(data);
205 assert_eq!($counter::<_, $type>(&mut rdr), $result);
206 })
207 }
208 #[bench]
209 fn $name_ser(b: &mut Bencher) {
210 let data = $data.as_bytes();
211 let values = ReaderBuilder::new()
212 .has_headers(true)
213 .from_reader(data)
214 .deserialize()
215 .collect::<Result<Vec<$type>, _>>()
216 .unwrap();
217
218 let do_it = || {
219 let mut counter = ByteCounter::default();
220 {
221 let mut wtr = WriterBuilder::new()
222 .has_headers(true)
223 .from_writer(&mut counter);
224 for val in &values {
225 wtr.serialize(val).unwrap();
226 }
227 }
228 counter.count
229 };
230 b.bytes = do_it() as u64;
231 b.iter(do_it)
232 }
233 };
234 }
235
236 macro_rules! bench_serde_borrowed_bytes {
237 ($name:ident, $data:ident, $type:ty, $headers:expr, $result:expr) => {
238 #[bench]
239 fn $name(b: &mut Bencher) {
240 let data = $data.as_bytes();
241 b.bytes = data.len() as u64;
242 b.iter(|| {
243 let mut rdr = ReaderBuilder::new()
244 .has_headers($headers)
245 .from_reader(data);
246 let mut count = 0;
247 let mut rec = ByteRecord::new();
248 while rdr.read_byte_record(&mut rec).unwrap() {
249 let _: $type = rec.deserialize(None).unwrap();
250 count += 1;
251 }
252 count
253 })
254 }
255 };
256 }
257
258 macro_rules! bench_serde_borrowed_str {
259 ($name:ident, $data:ident, $type:ty, $headers:expr, $result:expr) => {
260 #[bench]
261 fn $name(b: &mut Bencher) {
262 let data = $data.as_bytes();
263 b.bytes = data.len() as u64;
264 b.iter(|| {
265 let mut rdr = ReaderBuilder::new()
266 .has_headers($headers)
267 .from_reader(data);
268 let mut count = 0;
269 let mut rec = StringRecord::new();
270 while rdr.read_record(&mut rec).unwrap() {
271 let _: $type = rec.deserialize(None).unwrap();
272 count += 1;
273 }
274 count
275 })
276 }
277 };
278 }
279
280 bench_serde!(
281 count_nfl_deserialize_owned_bytes,
282 count_nfl_serialize_owned_bytes,
283 NFL,
284 count_deserialize_owned_bytes,
285 NFLRowOwned,
286 9999
287 );
288 bench_serde!(
289 count_nfl_deserialize_owned_str,
290 count_nfl_serialize_owned_str,
291 NFL,
292 count_deserialize_owned_str,
293 NFLRowOwned,
294 9999
295 );
296 bench_serde_borrowed_bytes!(
297 count_nfl_deserialize_borrowed_bytes,
298 NFL,
299 NFLRowBorrowed,
300 true,
301 9999
302 );
303 bench_serde_borrowed_str!(
304 count_nfl_deserialize_borrowed_str,
305 NFL,
306 NFLRowBorrowed,
307 true,
308 9999
309 );
310 bench!(count_nfl_iter_bytes, NFL, count_iter_bytes, 130000);
311 bench_trimmed!(count_nfl_iter_bytes_trimmed, NFL, count_iter_bytes, 130000);
312 bench!(count_nfl_iter_str, NFL, count_iter_str, 130000);
313 bench_trimmed!(count_nfl_iter_str_trimmed, NFL, count_iter_str, 130000);
314 bench!(count_nfl_read_bytes, NFL, count_read_bytes, 130000);
315 bench!(count_nfl_read_str, NFL, count_read_str, 130000);
316 bench_serde!(
317 no_headers,
318 count_game_deserialize_owned_bytes,
319 count_game_serialize_owned_bytes,
320 GAME,
321 count_deserialize_owned_bytes,
322 GAMERowOwned,
323 100000
324 );
325 bench_serde!(
326 no_headers,
327 count_game_deserialize_owned_str,
328 count_game_serialize_owned_str,
329 GAME,
330 count_deserialize_owned_str,
331 GAMERowOwned,
332 100000
333 );
334 bench_serde_borrowed_bytes!(
335 count_game_deserialize_borrowed_bytes,
336 GAME,
337 GAMERowBorrowed,
338 true,
339 100000
340 );
341 bench_serde_borrowed_str!(
342 count_game_deserialize_borrowed_str,
343 GAME,
344 GAMERowBorrowed,
345 true,
346 100000
347 );
348 bench!(count_game_iter_bytes, GAME, count_iter_bytes, 600000);
349 bench!(count_game_iter_str, GAME, count_iter_str, 600000);
350 bench!(count_game_read_bytes, GAME, count_read_bytes, 600000);
351 bench!(count_game_read_str, GAME, count_read_str, 600000);
352 bench_serde!(
353 count_pop_deserialize_owned_bytes,
354 count_pop_serialize_owned_bytes,
355 POP,
356 count_deserialize_owned_bytes,
357 POPRowOwned,
358 20000
359 );
360 bench_serde!(
361 count_pop_deserialize_owned_str,
362 count_pop_serialize_owned_str,
363 POP,
364 count_deserialize_owned_str,
365 POPRowOwned,
366 20000
367 );
368 bench_serde_borrowed_bytes!(
369 count_pop_deserialize_borrowed_bytes,
370 POP,
371 POPRowBorrowed,
372 true,
373 20000
374 );
375 bench_serde_borrowed_str!(
376 count_pop_deserialize_borrowed_str,
377 POP,
378 POPRowBorrowed,
379 true,
380 20000
381 );
382 bench!(count_pop_iter_bytes, POP, count_iter_bytes, 140007);
383 bench!(count_pop_iter_str, POP, count_iter_str, 140007);
384 bench!(count_pop_read_bytes, POP, count_read_bytes, 140007);
385 bench!(count_pop_read_str, POP, count_read_str, 140007);
386 bench_serde!(
387 count_mbta_deserialize_owned_bytes,
388 count_mbta_serialize_owned_bytes,
389 MBTA,
390 count_deserialize_owned_bytes,
391 MBTARowOwned,
392 9999
393 );
394 bench_serde!(
395 count_mbta_deserialize_owned_str,
396 count_mbta_serialize_owned_str,
397 MBTA,
398 count_deserialize_owned_str,
399 MBTARowOwned,
400 9999
401 );
402 bench_serde_borrowed_bytes!(
403 count_mbta_deserialize_borrowed_bytes,
404 MBTA,
405 MBTARowBorrowed,
406 true,
407 9999
408 );
409 bench_serde_borrowed_str!(
410 count_mbta_deserialize_borrowed_str,
411 MBTA,
412 MBTARowBorrowed,
413 true,
414 9999
415 );
416 bench!(count_mbta_iter_bytes, MBTA, count_iter_bytes, 90000);
417 bench!(count_mbta_iter_str, MBTA, count_iter_str, 90000);
418 bench!(count_mbta_read_bytes, MBTA, count_read_bytes, 90000);
419 bench!(count_mbta_read_str, MBTA, count_read_str, 90000);
420
421 macro_rules! bench_write {
422 ($name:ident, $data:ident) => {
423 #[bench]
424 fn $name(b: &mut Bencher) {
425 let data = $data.as_bytes();
426 b.bytes = data.len() as u64;
427 let records = collect_records(data);
428
429 b.iter(|| {
430 let mut wtr = Writer::from_writer(vec![]);
431 for r in &records {
432 wtr.write_record(r).unwrap();
433 }
434 assert!(wtr.flush().is_ok());
435 })
436 }
437 };
438 }
439
440 macro_rules! bench_write_bytes {
441 ($name:ident, $data:ident) => {
442 #[bench]
443 fn $name(b: &mut Bencher) {
444 let data = $data.as_bytes();
445 b.bytes = data.len() as u64;
446 let records = collect_records(data);
447
448 b.iter(|| {
449 let mut wtr = Writer::from_writer(vec![]);
450 for r in &records {
451 wtr.write_byte_record(r).unwrap();
452 }
453 assert!(wtr.flush().is_ok());
454 })
455 }
456 };
457 }
458
459 bench_write!(write_nfl_record, NFL);
460 bench_write_bytes!(write_nfl_bytes, NFL);
461
462 fn count_deserialize_owned_bytes<R, D>(rdr: &mut Reader<R>) -> u64
463 where
464 R: io::Read,
465 D: DeserializeOwned,
466 {
467 let mut count = 0;
468 let mut rec = ByteRecord::new();
469 while rdr.read_byte_record(&mut rec).unwrap() {
470 let _: D = rec.deserialize(None).unwrap();
471 count += 1;
472 }
473 count
474 }
475
476 fn count_deserialize_owned_str<R, D>(rdr: &mut Reader<R>) -> u64
477 where
478 R: io::Read,
479 D: DeserializeOwned,
480 {
481 let mut count = 0;
482 for rec in rdr.deserialize::<D>() {
483 let _ = rec.unwrap();
484 count += 1;
485 }
486 count
487 }
488
489 fn count_iter_bytes<R: io::Read>(rdr: &mut Reader<R>) -> u64 {
490 let mut count = 0;
491 for rec in rdr.byte_records() {
492 count += rec.unwrap().len() as u64;
493 }
494 count
495 }
496
497 fn count_iter_str<R: io::Read>(rdr: &mut Reader<R>) -> u64 {
498 let mut count = 0;
499 for rec in rdr.records() {
500 count += rec.unwrap().len() as u64;
501 }
502 count
503 }
504
505 fn count_read_bytes<R: io::Read>(rdr: &mut Reader<R>) -> u64 {
506 let mut count = 0;
507 let mut rec = ByteRecord::new();
508 while rdr.read_byte_record(&mut rec).unwrap() {
509 count += rec.len() as u64;
510 }
511 count
512 }
513
514 fn count_read_str<R: io::Read>(rdr: &mut Reader<R>) -> u64 {
515 let mut count = 0;
516 let mut rec = StringRecord::new();
517 while rdr.read_record(&mut rec).unwrap() {
518 count += rec.len() as u64;
519 }
520 count
521 }
522
523 fn collect_records(data: &[u8]) -> Vec<ByteRecord> {
524 let mut rdr = ReaderBuilder::new().has_headers(false).from_reader(data);
525 rdr.byte_records().collect::<Result<Vec<_>, _>>().unwrap()
526 }