AdamGS commented on PR #628:
URL: 
https://github.com/apache/arrow-rs-object-store/pull/628#issuecomment-3817191279

   Running the following benchmark, I see a pretty solid improvement on my 
macbook pro, but I'll try and find the time to benchmark it on some AWS box.
   
   Criterion results (compared to most recent `main` as of this writing):
   ```
   read_ranges/local_fs/10 time:   [23.699 µs 23.957 µs 24.288 µs]
                           thrpt:  [3.1412 GiB/s 3.1847 GiB/s 3.2192 GiB/s]
                    change:
                           time:   [−7.8715% −5.3115% −1.1817%] (p = 0.00 < 
0.05)
                           thrpt:  [+1.1958% +5.6094% +8.5440%]
                           Performance has improved.
   Found 1 outliers among 100 measurements (1.00%)
     1 (1.00%) high severe
   read_ranges/local_fs/100
                           time:   [86.424 µs 87.314 µs 88.361 µs]
                           thrpt:  [8.6343 GiB/s 8.7379 GiB/s 8.8278 GiB/s]
                    change:
                           time:   [−25.457% −24.045% −22.676%] (p = 0.00 < 
0.05)
                           thrpt:  [+29.326% +31.658% +34.150%]
                           Performance has improved.
   Found 13 outliers among 100 measurements (13.00%)
     6 (6.00%) high mild
     7 (7.00%) high severe
   Benchmarking read_ranges/local_fs/1000: Warming up for 3.0000 s
   Warning: Unable to complete 100 samples in 5.0s. You may wish to increase 
target time to 5.2s, enable flat sampling, or reduce sample count to 60.
   read_ranges/local_fs/1000
                           time:   [984.16 µs 996.91 µs 1.0117 ms]
                           thrpt:  [7.5414 GiB/s 7.6530 GiB/s 7.7522 GiB/s]
                    change:
                           time:   [−22.534% −20.385% −18.156%] (p = 0.00 < 
0.05)
                           thrpt:  [+22.183% +25.604% +29.088%]
                           Performance has improved.
   Found 5 outliers among 100 measurements (5.00%)
     5 (5.00%) high severe
   
   get_opts_whole_file/local_fs
                           time:   [7.8658 ms 7.8872 ms 7.9107 ms]
                           thrpt:  [7.9007 GiB/s 7.9242 GiB/s 7.9458 GiB/s]
                    change:
                           time:   [−1.6425% −1.2214% −0.8096%] (p = 0.00 < 
0.05)
                           thrpt:  [+0.8162% +1.2365% +1.6699%]
                           Change within noise threshold.
   Found 5 outliers among 100 measurements (5.00%)
     2 (2.00%) high mild
     3 (3.00%) high severe
   
   get_range_sequential/local_fs/10
                           time:   [206.23 µs 209.19 µs 212.59 µs]
                           thrpt:  [367.50 MiB/s 373.46 MiB/s 378.82 MiB/s]
                    change:
                           time:   [−15.312% −14.118% −12.898%] (p = 0.00 < 
0.05)
                           thrpt:  [+14.808% +16.439% +18.081%]
                           Performance has improved.
   Found 11 outliers among 100 measurements (11.00%)
     8 (8.00%) high mild
     3 (3.00%) high severe
   get_range_sequential/local_fs/100
                           time:   [2.0626 ms 2.0773 ms 2.0948 ms]
                           thrpt:  [372.95 MiB/s 376.08 MiB/s 378.77 MiB/s]
                    change:
                           time:   [−14.729% −13.884% −12.938%] (p = 0.00 < 
0.05)
                           thrpt:  [+14.861% +16.123% +17.273%]
                           Performance has improved.
   Found 7 outliers among 100 measurements (7.00%)
     4 (4.00%) high mild
     3 (3.00%) high severe
   get_range_sequential/local_fs/1000
                           time:   [23.157 ms 23.363 ms 23.596 ms]
                           thrpt:  [331.09 MiB/s 334.39 MiB/s 337.37 MiB/s]
                    change:
                           time:   [−1.0249% +0.0131% +1.2791%] (p = 0.98 > 
0.05)
                           thrpt:  [−1.2630% −0.0131% +1.0356%]
                           No change in performance detected.
   Found 6 outliers among 100 measurements (6.00%)
     1 (1.00%) high mild
     5 (5.00%) high severe
   ```
   
   Code for the benchmark, mostly doing 8KB reads and some full file reads 
(64MB), happy to add more cases that might be interesting:
   ```rust
   use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, 
criterion_main};
   use object_store::local::LocalFileSystem;
   use object_store::path::Path;
   use object_store::{ObjectStore, ObjectStoreExt};
   use rand::Rng;
   use std::ops::Range;
   use tempfile::TempDir;
   
   const FILE_SIZE: u64 = 64 * 1024 * 1024; // 64 MB
   const RANGE_SIZE: u64 = 8 * 1024; // 8 KB ranges
   
   fn generate_random_ranges(file_size: u64, range_size: u64, count: usize) -> 
Vec<Range<u64>> {
       let mut rng = rand::rng();
       (0..count)
           .map(|_| {
               let start = rng.random_range(0..file_size - range_size);
               start..start + range_size
           })
           .collect()
   }
   
   fn bench_read_ranges(c: &mut Criterion) {
       let rt = tokio::runtime::Builder::new_current_thread()
           .enable_all()
           .build()
           .unwrap();
   
       // Set up the test file
       let temp_dir = TempDir::new().unwrap();
       let store = LocalFileSystem::new_with_prefix(temp_dir.path()).unwrap();
       let path = Path::from("bench_file");
   
       // Create file with random data
       let data: Vec<u8> = (0..FILE_SIZE).map(|i| (i % 256) as u8).collect();
       rt.block_on(async {
           store.put(&path, data.into()).await.unwrap();
       });
   
       let mut group = c.benchmark_group("read_ranges");
   
       for num_ranges in [10, 100, 1000] {
           let ranges = generate_random_ranges(FILE_SIZE, RANGE_SIZE, 
num_ranges);
           let total_bytes = num_ranges as u64 * RANGE_SIZE;
   
           group.throughput(Throughput::Bytes(total_bytes));
           group.bench_with_input(
               BenchmarkId::new("local_fs", num_ranges),
               &ranges,
               |b, ranges| {
                   b.to_async(&rt)
                       .iter(|| async { store.get_ranges(&path, 
ranges).await.unwrap() });
               },
           );
       }
   
       group.finish();
   }
   
   fn bench_get_opts_whole_file(c: &mut Criterion) {
       let rt = tokio::runtime::Builder::new_current_thread()
           .enable_all()
           .build()
           .unwrap();
   
       let temp_dir = TempDir::new().unwrap();
       let store = LocalFileSystem::new_with_prefix(temp_dir.path()).unwrap();
       let path = Path::from("bench_file");
   
       let data: Vec<u8> = (0..FILE_SIZE).map(|i| (i % 256) as u8).collect();
       rt.block_on(async {
           store.put(&path, data.into()).await.unwrap();
       });
   
       let mut group = c.benchmark_group("get_opts_whole_file");
       group.throughput(Throughput::Bytes(FILE_SIZE));
   
       group.bench_function("local_fs", |b| {
           b.to_async(&rt).iter(|| async {
               store
                   .get_opts(&path, Default::default())
                   .await
                   .unwrap()
                   .bytes()
                   .await
                   .unwrap()
           });
       });
   
       group.finish();
   }
   
   fn bench_get_range_sequential(c: &mut Criterion) {
       let rt = tokio::runtime::Builder::new_current_thread()
           .enable_all()
           .build()
           .unwrap();
   
       let temp_dir = TempDir::new().unwrap();
       let store = LocalFileSystem::new_with_prefix(temp_dir.path()).unwrap();
       let path = Path::from("bench_file");
   
       let data: Vec<u8> = (0..FILE_SIZE).map(|i| (i % 256) as u8).collect();
       rt.block_on(async {
           store.put(&path, data.into()).await.unwrap();
       });
   
       let mut group = c.benchmark_group("get_range_sequential");
   
       for num_ranges in [10, 100, 1000] {
           let ranges = generate_random_ranges(FILE_SIZE, RANGE_SIZE, 
num_ranges);
           let total_bytes = num_ranges as u64 * RANGE_SIZE;
   
           group.throughput(Throughput::Bytes(total_bytes));
           group.bench_with_input(
               BenchmarkId::new("local_fs", num_ranges),
               &ranges,
               |b, ranges| {
                   b.to_async(&rt).iter(|| async {
                       for range in ranges {
                           store.get_range(&path, range.clone()).await.unwrap();
                       }
                   });
               },
           );
       }
   
       group.finish();
   }
   
   criterion_group!(
       benches,
       bench_read_ranges,
       bench_get_opts_whole_file,
       bench_get_range_sequential
   );
   criterion_main!(benches);
   
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to