pub struct ConcurrentWrapper<P: ProgressLog = ProgressLogger> { /* private fields */ }Expand description
A ConcurrentProgressLog implementation that wraps a ProgressLog in
an Arc/Mutex.
The methods update and
update_with_count buffer the increment
and add it to the underlying logger only when the buffer reaches a
threshold; this prevents locking the underlying logger too often. The
threshold is set at creation using the methods
with_threshold and
wrap_with_threshold, or by calling the method
threshold.
The method light_update, as in the case of
ProgressLogger, further delays updates using an even faster check.
§Examples
In this example, we manually spawn processes:
use dsi_progress_logger::prelude::*;
use std::thread;
let mut cpl = concurrent_progress_logger![item_name = "pumpkin"];
cpl.start("Smashing pumpkins (using many threads)...");
std::thread::scope(|s| {
for i in 0..100 {
let mut pl = cpl.clone();
s.spawn(move || {
for _ in 0..100000 {
// do something on each pumpkin
pl.update();
}
});
}
});
cpl.done();You can obtain the same behavior with
rayon using methods such as
for_each_with
and
map_with:
use dsi_progress_logger::prelude::*;
use rayon::prelude::*;
let mut cpl = concurrent_progress_logger![item_name = "pumpkin"];
cpl.start("Smashing pumpkins (using many threads)...");
(0..1000000).into_par_iter().
with_min_len(1000). // optional, might reduce the amount of cloning
for_each_with(cpl.clone(), |pl, i| {
// do something on each pumpkin
pl.update();
}
);
cpl.done();Note that you have to pass cpl.clone() to avoid a move that would make the
call to done impossible. Also, since
for_each_with
might perform excessive cloning if jobs are too short, you can use
with_min_len
to reduce the amount of cloning.
Implementations§
Source§impl ConcurrentWrapper
impl ConcurrentWrapper
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new ConcurrentWrapper based on a default
ProgressLogger, using the default
threshold.
Sourcepub fn with_threshold(threshold: u32) -> Self
pub fn with_threshold(threshold: u32) -> Self
Create a new ConcurrentWrapper wrapping a default
ProgressLogger, using the given threshold.
Source§impl<P: ProgressLog> ConcurrentWrapper<P>
impl<P: ProgressLog> ConcurrentWrapper<P>
Sourcepub const DEFAULT_THRESHOLD: u32 = 32_768u32
pub const DEFAULT_THRESHOLD: u32 = 32_768u32
The default threshold for updating the underlying logger.
Sourcepub const LIGHT_UPDATE_MASK: u32 = 1_023u32
pub const LIGHT_UPDATE_MASK: u32 = 1_023u32
Calls to light_update will cause a call
to update_with_count only if the
current local count is a multiple of this mask plus one.
Note that this constant is significantly smaller than the one used in
ProgressLogger, as updates will be further delayed by the threshold
mechanism.
Sourcepub fn threshold(&mut self, threshold: u32) -> &mut Self
pub fn threshold(&mut self, threshold: u32) -> &mut Self
Set the threshold for updating the underlying logger.
Note that concurrent loggers with the same underlying logger have independent thresholds.
Sourcepub fn wrap(inner: P) -> Self
pub fn wrap(inner: P) -> Self
Wrap a given ProgressLog in a ConcurrentWrapper
using the default threshold.
Sourcepub fn wrap_with_threshold(inner: P, threshold: u32) -> Self
pub fn wrap_with_threshold(inner: P, threshold: u32) -> Self
Wrap a given ProgressLog in a ConcurrentWrapper using a
given threshold.
Source§impl<P: ProgressLog + Clone> ConcurrentWrapper<P>
impl<P: ProgressLog + Clone> ConcurrentWrapper<P>
Sourcepub fn dup(&self) -> Self
pub fn dup(&self) -> Self
Duplicates the concurrent wrapper, obtaining a new one with the same
threshold, with a local count of zero, and with an inner
ProgressLog that is a clone of the original one.
Trait Implementations§
Source§impl<P: ProgressLog + Clone> Clone for ConcurrentWrapper<P>
impl<P: ProgressLog + Clone> Clone for ConcurrentWrapper<P>
Source§fn clone(&self) -> Self
fn clone(&self) -> Self
Clone the concurrent wrapper, obtaining a new one with the same
threshold, with a local count of zero, and with the same inner
ProgressLog.
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<P: ProgressLog + Clone + Send> ConcurrentProgressLog for ConcurrentWrapper<P>
impl<P: ProgressLog + Clone + Send> ConcurrentProgressLog for ConcurrentWrapper<P>
Source§type Duplicated = ConcurrentWrapper<P>
type Duplicated = ConcurrentWrapper<P>
dup.Source§impl Default for ConcurrentWrapper
impl Default for ConcurrentWrapper
Source§fn default() -> Self
fn default() -> Self
Create a new ConcurrentWrapper based on a default
ProgressLogger, with a threshold of
DEFAULT_THRESHOLD.
Source§impl Display for ConcurrentWrapper
impl Display for ConcurrentWrapper
Source§impl<P: ProgressLog> Drop for ConcurrentWrapper<P>
This implementation just calls flush,
type Concurrent = Option<P::Concurrent>;
impl<P: ProgressLog> Drop for ConcurrentWrapper<P>
This implementation just calls flush,
type Concurrent = Option<P::Concurrent>;
to guarantee that all updates are correctly passed to the underlying logger.
Source§impl<P: ProgressLog + Clone + Send> ProgressLog for ConcurrentWrapper<P>
impl<P: ProgressLog + Clone + Send> ProgressLog for ConcurrentWrapper<P>
Source§type Concurrent = ConcurrentWrapper<P>
type Concurrent = ConcurrentWrapper<P>
concurrent.Source§fn add_to_count(&mut self, count: usize)
fn add_to_count(&mut self, count: usize)
Source§fn display_memory(&mut self, display_memory: bool) -> &mut Self
fn display_memory(&mut self, display_memory: bool) -> &mut Self
Source§fn log_interval(&mut self, log_interval: Duration) -> &mut Self
fn log_interval(&mut self, log_interval: Duration) -> &mut Self
Source§fn expected_updates(&mut self, expected_updates: Option<usize>) -> &mut Self
fn expected_updates(&mut self, expected_updates: Option<usize>) -> &mut Self
Source§fn time_unit(&mut self, time_unit: Option<TimeUnit>) -> &mut Self
fn time_unit(&mut self, time_unit: Option<TimeUnit>) -> &mut Self
Source§fn local_speed(&mut self, local_speed: bool) -> &mut Self
fn local_speed(&mut self, local_speed: bool) -> &mut Self
Source§fn start(&mut self, msg: impl AsRef<str>)
fn start(&mut self, msg: impl AsRef<str>)
Source§fn update_with_count_and_time(&mut self, count: usize, _now: Instant)
fn update_with_count_and_time(&mut self, count: usize, _now: Instant)
Source§fn update_with_count(&mut self, count: usize)
fn update_with_count(&mut self, count: usize)
Source§fn light_update(&mut self)
fn light_update(&mut self)
Source§fn update_and_display(&mut self)
fn update_and_display(&mut self)
Source§fn done(&mut self)
fn done(&mut self)
Completed., and display the final stats. The
number of expected updates will be cleared.Source§fn done_with_count(&mut self, count: usize)
fn done_with_count(&mut self, count: usize)
Completed., and displays the
final stats. The number of expected updates will be cleared. Read moreSource§fn elapsed(&self) -> Option<Duration>
fn elapsed(&self) -> Option<Duration>
None if the
logger has not been started.Source§fn refresh(&mut self)
fn refresh(&mut self)
display_memory. You do not need to call this
method unless you display the logger manually.