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, obtaning 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, obtaning 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.Source§fn concurrent(&self) -> Self::Concurrent
fn concurrent(&self) -> Self::Concurrent
Auto Trait Implementations§
impl<P> Freeze for ConcurrentWrapper<P>
impl<P> RefUnwindSafe for ConcurrentWrapper<P>
impl<P> Send for ConcurrentWrapper<P>where
P: Send,
impl<P> Sync for ConcurrentWrapper<P>where
P: Send,
impl<P> Unpin for ConcurrentWrapper<P>
impl<P> UnwindSafe for ConcurrentWrapper<P>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more