diff --git a/flamegraphs/11-multithreading-single-memory-space/flamegraph.svg b/flamegraphs/11-multithreading-single-memory-space/flamegraph.svg new file mode 100644 index 0000000..09579b5 --- /dev/null +++ b/flamegraphs/11-multithreading-single-memory-space/flamegraph.svg @@ -0,0 +1,491 @@ +Flame Graph Reset ZoomSearch [unknown] (28 samples, 0.03%)[unknown] (20 samples, 0.02%)[unknown] (13 samples, 0.01%)core::cell::Cell<T>::set (16 samples, 0.02%)core::cell::Cell<T>::replace (16 samples, 0.02%)core::mem::replace (16 samples, 0.02%)core::ptr::read (16 samples, 0.02%)<crossbeam_channel::select::Selected as core::convert::From<usize>>::from (42 samples, 0.04%)__sched_yield (40 samples, 0.04%)[unknown] (39 samples, 0.04%)[unknown] (37 samples, 0.04%)[unknown] (37 samples, 0.04%)[unknown] (37 samples, 0.04%)[unknown] (34 samples, 0.04%)[unknown] (29 samples, 0.03%)[unknown] (24 samples, 0.03%)[unknown] (19 samples, 0.02%)[unknown] (14 samples, 0.01%)core::hint::spin_loop (242 samples, 0.26%)core::core_arch::x86::sse2::_mm_pause (242 samples, 0.26%)crossbeam_utils::backoff::Backoff::snooze (285 samples, 0.30%)crossbeam_channel::context::Context::with::_{{closure}} (398 samples, 0.42%)crossbeam_channel::context::Context::with::_{{closure}} (382 samples, 0.40%)crossbeam_channel::flavors::array::Channel<T>::recv::_{{closure}} (378 samples, 0.40%)crossbeam_channel::context::Context::wait_until (376 samples, 0.40%)std::thread::park (42 samples, 0.04%)syscall (14 samples, 0.01%)[unknown] (14 samples, 0.01%)[unknown] (14 samples, 0.01%)[unknown] (14 samples, 0.01%)[unknown] (14 samples, 0.01%)[unknown] (14 samples, 0.01%)[unknown] (13 samples, 0.01%)[unknown] (10 samples, 0.01%)crossbeam_channel::context::Context::with (399 samples, 0.42%)std::thread::local::LocalKey<T>::try_with (399 samples, 0.42%)crossbeam_channel::flavors::array::Channel<T>::read (16 samples, 0.02%)crossbeam_channel::waker::SyncWaker::notify (15 samples, 0.02%)crossbeam_channel::flavors::array::Channel<T>::start_recv (98 samples, 0.10%)core::sync::atomic::AtomicUsize::load (48 samples, 0.05%)core::sync::atomic::atomic_load (48 samples, 0.05%)__sched_yield (63 samples, 0.07%)[unknown] (61 samples, 0.06%)[unknown] (59 samples, 0.06%)[unknown] (54 samples, 0.06%)[unknown] (53 samples, 0.06%)[unknown] (42 samples, 0.04%)[unknown] (38 samples, 0.04%)[unknown] (30 samples, 0.03%)[unknown] (24 samples, 0.03%)[unknown] (22 samples, 0.02%)[unknown] (10 samples, 0.01%)core::iter::range::<impl core::iter::traits::iterator::Iterator for core::ops::range::Range<A>>::next (350 samples, 0.37%)<core::ops::range::Range<T> as core::iter::range::RangeIteratorImpl>::spec_next (350 samples, 0.37%)core::cmp::impls::<impl core::cmp::PartialOrd for i32>::lt (331 samples, 0.35%)<crossbeam_channel::channel::IntoIter<T> as core::iter::traits::iterator::Iterator>::next (941 samples, 0.99%)crossbeam_channel::channel::Receiver<T>::recv (941 samples, 0.99%)crossbeam_channel::flavors::array::Channel<T>::recv (940 samples, 0.99%)crossbeam_utils::backoff::Backoff::snooze (419 samples, 0.44%)[libc.so.6] (16 samples, 0.02%)[libc.so.6] (96 samples, 0.10%)cfree (150 samples, 0.16%)__lll_lock_wake_private (48 samples, 0.05%)[unknown] (48 samples, 0.05%)[unknown] (46 samples, 0.05%)[unknown] (42 samples, 0.04%)[unknown] (38 samples, 0.04%)[unknown] (36 samples, 0.04%)core::ptr::drop_in_place<alloc::boxed::Box<[u8]>> (152 samples, 0.16%)<alloc::boxed::Box<T,A> as core::ops::drop::Drop>::drop (152 samples, 0.16%)<alloc::alloc::Global as core::alloc::Allocator>::deallocate (151 samples, 0.16%)alloc::alloc::dealloc (151 samples, 0.16%)__rdl_alloc (528 samples, 0.56%)__rust_alloc (522 samples, 0.55%)core::ptr::read_volatile (40 samples, 0.04%)alloc::raw_vec::RawVec<T>::with_capacity (10,631 samples, 11.21%)alloc::raw_vec::..alloc::raw_vec::RawVec<T,A>::with_capacity_in (10,631 samples, 11.21%)alloc::raw_vec::..alloc::raw_vec::RawVec<T,A>::allocate_in (10,631 samples, 11.21%)alloc::raw_vec::..<alloc::alloc::Global as core::alloc::Allocator>::allocate (10,610 samples, 11.19%)<alloc::alloc::G..alloc::alloc::Global::alloc_impl (10,610 samples, 11.19%)alloc::alloc::Gl..alloc::alloc::alloc (10,610 samples, 11.19%)alloc::alloc::al..malloc (7,799 samples, 8.22%)malloc<T as core::convert::Into<U>>::into (13,731 samples, 14.48%)<T as core::convert::I..<alloc::boxed::Box<[T]> as core::convert::From<&[T]>>::from (13,731 samples, 14.48%)<alloc::boxed::Box<[T]..<alloc::boxed::Box<[T]> as alloc::boxed::BoxFromSlice<T>>::from_slice (13,731 samples, 14.48%)<alloc::boxed::Box<[T]..core::intrinsics::copy_nonoverlapping (3,100 samples, 3.27%)cor..[libc.so.6] (3,083 samples, 3.25%)[li..<core::ops::range::Range<usize> as core::slice::index::SliceIndex<[T]>>::index (778 samples, 0.82%)core::slice::index::<impl core::ops::index::Index<I> for [T]>::index (1,816 samples, 1.91%)c..<core::ops::range::RangeFrom<usize> as core::slice::index::SliceIndex<[T]>>::index (1,038 samples, 1.09%)<f32 as core::ops::arith::Div>::div (101 samples, 0.11%)<f32 as fast_float::float::Float>::from_u64 (770 samples, 0.81%)<f32 as fast_float::float::Float>::pow10_fast_path (22 samples, 0.02%)fast_float::number::Number::try_fast_path (2,835 samples, 2.99%)fas..fast_float::number::Number::is_fast_path (544 samples, 0.57%)fast_float::common::AsciiStr::check_first (775 samples, 0.82%)fast_float::common::AsciiStr::is_empty (720 samples, 0.76%)fast_float::common::AsciiStr::check_first_either (271 samples, 0.29%)fast_float::common::AsciiStr::is_empty (239 samples, 0.25%)fast_float::common::AsciiStr::first (35 samples, 0.04%)fast_float::common::AsciiStr::offset_from (12 samples, 0.01%)core::num::<impl isize>::wrapping_sub (12 samples, 0.01%)fast_float::number::try_parse_8digits_le (555 samples, 0.59%)fast_float::common::AsciiStr::try_read_u64 (555 samples, 0.59%)fast_float::common::AsciiStr::check_len (326 samples, 0.34%)core::ptr::const_ptr::<impl *const T>::add (15 samples, 0.02%)core::num::<impl u8>::is_ascii_digit (1,284 samples, 1.35%)fast_float::common::AsciiStr::first (209 samples, 0.22%)fast_float::common::AsciiStr::is_empty (743 samples, 0.78%)fast_float::common::AsciiStr::step (254 samples, 0.27%)fast_float::common::AsciiStr::step_by (254 samples, 0.27%)core::ptr::const_ptr::<impl *const T>::add (254 samples, 0.27%)fast_float::common::AsciiStr::parse_digits (4,340 samples, 4.58%)fast_..fast_float::number::try_parse_digits::_{{closure}} (652 samples, 0.69%)core::num::<impl u64>::wrapping_add (289 samples, 0.30%)fast_float::number::parse_number (12,725 samples, 13.42%)fast_float::number::..fast_float::number::try_parse_digits (4,379 samples, 4.62%)fast_..rust_1brc::process_chunk (39 samples, 0.04%)fast_float::parse (16,484 samples, 17.38%)fast_float::parsefast_float::FastFloat::parse_float (16,484 samples, 17.38%)fast_float::FastFloat::pars..fast_float::FastFloat::parse_float_partial (16,484 samples, 17.38%)fast_float::FastFloat::pars..fast_float::parse::parse_float (16,484 samples, 17.38%)fast_float::parse::parse_fl..rust_1brc::process_chunk (372 samples, 0.39%)<*const T as memchr::ext::Pointer>::distance (23 samples, 0.02%)core::ptr::const_ptr::<impl *const T>::offset_from (23 samples, 0.02%)<core::option::Option<T> as core::ops::try_trait::Try>::branch (186 samples, 0.20%)core::sync::atomic::AtomicPtr<T>::load (112 samples, 0.12%)core::sync::atomic::atomic_load (112 samples, 0.12%)<*const T as memchr::ext::Pointer>::distance (61 samples, 0.06%)core::ptr::const_ptr::<impl *const T>::offset_from (61 samples, 0.06%)<memchr::vector::SensibleMoveMask as memchr::vector::MoveMask>::has_non_zero (19 samples, 0.02%)memchr::vector::x86sse2::<impl memchr::vector::Vector for core::core_arch::x86::__m128i>::cmpeq (580 samples, 0.61%)core::core_arch::x86::sse2::_mm_cmpeq_epi8 (580 samples, 0.61%)memchr::arch::generic::memchr::One<V>::search_chunk (4,757 samples, 5.02%)memchr..memchr::vector::x86sse2::<impl memchr::vector::Vector for core::core_arch::x86::__m128i>::movemask (1,221 samples, 1.29%)core::core_arch::x86::sse2::_mm_movemask_epi8 (1,221 samples, 1.29%)memchr::vector::Vector::movemask_will_have_non_zero (12 samples, 0.01%)memchr::vector::x86sse2::<impl memchr::vector::Vector for core::core_arch::x86::__m128i>::movemask (12 samples, 0.01%)core::core_arch::x86::sse2::_mm_movemask_epi8 (12 samples, 0.01%)core::core_arch::x86::sse2::_mm_cmpeq_epi8 (55 samples, 0.06%)memchr::vector::x86sse2::<impl memchr::vector::Vector for core::core_arch::x86::__m128i>::cmpeq (102 samples, 0.11%)memchr::arch::x86_64::memchr::memchr_raw::find_sse2 (47 samples, 0.05%)memchr::arch::generic::memchr::search_slice_with_raw (8,917 samples, 9.40%)memchr::arch:..memchr::memchr::memchr::_{{closure}} (8,675 samples, 9.15%)memchr::memch..memchr::memchr::memchr_raw (8,675 samples, 9.15%)memchr::memch..memchr::arch::x86_64::memchr::memchr_raw (8,675 samples, 9.15%)memchr::arch:..memchr::arch::x86_64::memchr::memchr_raw::find_sse2 (8,085 samples, 8.52%)memchr::arch..memchr::arch::x86_64::sse2::memchr::One::find_raw (5,490 samples, 5.79%)memchr:..memchr::arch::x86_64::sse2::memchr::One::find_raw_impl (5,036 samples, 5.31%)memchr..memchr::arch::generic::memchr::One<V>::find_raw (5,036 samples, 5.31%)memchr..memchr::vector::x86sse2::<impl memchr::vector::Vector for core::core_arch::x86::__m128i>::or (20 samples, 0.02%)core::core_arch::x86::sse2::_mm_or_si128 (20 samples, 0.02%)memchr::memchr::memchr (8,920 samples, 9.40%)memchr::memch..std::collections::hash::map::Entry<K,V>::and_modify (1,184 samples, 1.25%)rust_1brc::process_chunk::_{{closure}} (1,184 samples, 1.25%)__rdl_dealloc (461 samples, 0.49%)__rust_dealloc (1,032 samples, 1.09%)[libc.so.6] (5,061 samples, 5.34%)[libc.s..std::collections::hash::map::OccupiedEntry<K,V>::into_mut (9,493 samples, 10.01%)std::collectio..hashbrown::rustc_entry::RustcOccupiedEntry<K,V,A>::into_mut (9,493 samples, 10.01%)hashbrown::rus..core::ptr::drop_in_place<hashbrown::rustc_entry::RustcOccupiedEntry<alloc::boxed::Box<[u8]>,rust_1brc::StationValues>> (9,493 samples, 10.01%)core::ptr::dro..core::ptr::drop_in_place<core::option::Option<alloc::boxed::Box<[u8]>>> (9,493 samples, 10.01%)core::ptr::dro..core::ptr::drop_in_place<alloc::boxed::Box<[u8]>> (9,474 samples, 9.99%)core::ptr::dro..<alloc::boxed::Box<T,A> as core::ops::drop::Drop>::drop (9,474 samples, 9.99%)<alloc::boxed:..<alloc::alloc::Global as core::alloc::Allocator>::deallocate (9,474 samples, 9.99%)<alloc::alloc:..alloc::alloc::dealloc (9,474 samples, 9.99%)alloc::alloc::..cfree (7,981 samples, 8.41%)cfreestd::collections::hash::map::Entry<K,V>::or_insert (9,497 samples, 10.01%)std::collectio..hashbrown::map::HashMap<K,V,S,A>::reserve (12 samples, 0.01%)hashbrown::raw::RawTable<T,A>::reserve (12 samples, 0.01%)hashbrown::raw::RawTable<T,A>::reserve_rehash (11 samples, 0.01%)hashbrown::raw::RawTableInner::reserve_rehash_inner (10 samples, 0.01%)hashbrown::raw::RawTableInner::resize_inner (10 samples, 0.01%)core::hash::Hasher::write_length_prefix (67 samples, 0.07%)<rustc_hash::FxHasher as core::hash::Hasher>::write_usize (67 samples, 0.07%)rustc_hash::FxHasher::add_to_hash (67 samples, 0.07%)core::num::<impl usize>::wrapping_mul (67 samples, 0.07%)core::slice::index::<impl core::ops::index::Index<I> for [T]>::index (505 samples, 0.53%)<core::ops::range::RangeFrom<usize> as core::slice::index::SliceIndex<[T]>>::index (505 samples, 0.53%)<core::ops::range::RangeFrom<usize> as core::slice::index::SliceIndex<[T]>>::get_unchecked (505 samples, 0.53%)<core::ops::range::Range<usize> as core::slice::index::SliceIndex<[T]>>::get_unchecked (505 samples, 0.53%)core::ptr::const_ptr::<impl *const T>::add (11 samples, 0.01%)<usize as core::ops::bit::BitXor>::bitxor (340 samples, 0.36%)core::num::<impl usize>::rotate_left (2,332 samples, 2.46%)co..<rustc_hash::FxHasher as core::hash::Hasher>::write (8,172 samples, 8.62%)<rustc_hash:..rustc_hash::FxHasher::add_to_hash (5,256 samples, 5.54%)rustc_h..core::num::<impl usize>::wrapping_mul (2,584 samples, 2.72%)co..hashbrown::map::make_hash (8,263 samples, 8.71%)hashbrown::m..core::hash::BuildHasher::hash_one (8,263 samples, 8.71%)core::hash::..core::hash::impls::<impl core::hash::Hash for &T>::hash (8,263 samples, 8.71%)core::hash::..<alloc::boxed::Box<T,A> as core::hash::Hash>::hash (8,263 samples, 8.71%)<alloc::boxe..core::hash::impls::<impl core::hash::Hash for [T]>::hash (8,263 samples, 8.71%)core::hash::..core::hash::impls::<impl core::hash::Hash for u8>::hash_slice (8,196 samples, 8.64%)core::hash::..hashbrown::rustc_entry::<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (24 samples, 0.03%)core::num::nonzero::NonZero<u16>::new (60 samples, 0.06%)<hashbrown::raw::bitmask::BitMaskIter as core::iter::traits::iterator::Iterator>::next (69 samples, 0.07%)hashbrown::raw::bitmask::BitMask::lowest_set_bit (69 samples, 0.07%)hashbrown::raw::RawTable<T,A>::bucket (877 samples, 0.92%)hashbrown::raw::Bucket<T>::from_base_index (877 samples, 0.92%)core::ptr::mut_ptr::<impl *mut T>::sub (877 samples, 0.92%)core::ptr::mut_ptr::<impl *mut T>::offset (877 samples, 0.92%)[libc.so.6] (8,491 samples, 8.95%)[libc.so.6]<[A] as core::slice::cmp::SlicePartialEq<B>>::equal (13,510 samples, 14.24%)<[A] as core::slice::c..hashbrown::raw::RawTable<T,A>::find::_{{closure}} (14,398 samples, 15.18%)hashbrown::raw::RawTabl..hashbrown::rustc_entry::_<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry::_{{closure}} (13,518 samples, 14.25%)hashbrown::rustc_entry..<alloc::boxed::Box<T,A> as core::cmp::PartialEq>::eq (13,518 samples, 14.25%)<alloc::boxed::Box<T,A..core::slice::cmp::<impl core::cmp::PartialEq<[B]> for [A]>::eq (13,518 samples, 14.25%)core::slice::cmp::<imp..hashbrown::raw::h2 (2,871 samples, 3.03%)has..core::intrinsics::copy_nonoverlapping (20 samples, 0.02%)hashbrown::raw::sse2::Group::load (482 samples, 0.51%)core::core_arch::x86::sse2::_mm_loadu_si128 (482 samples, 0.51%)hashbrown::rustc_entry::<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (462 samples, 0.49%)hashbrown::raw::sse2::Group::match_byte (4,412 samples, 4.65%)hashb..core::core_arch::x86::sse2::_mm_movemask_epi8 (4,412 samples, 4.65%)core:..hashbrown::raw::sse2::Group::match_empty (416 samples, 0.44%)hashbrown::raw::sse2::Group::match_byte (416 samples, 0.44%)core::core_arch::x86::sse2::_mm_movemask_epi8 (416 samples, 0.44%)hashbrown::raw::RawTableInner::find_inner (25,613 samples, 27.00%)hashbrown::raw::RawTableInner::find_innerhashbrown::rustc_entry::<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (48 samples, 0.05%)hashbrown::rustc_entry::<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (38,377 samples, 40.46%)hashbrown::rustc_entry::<impl hashbrown::map::HashMap<K,V,S,A>>::r..hashbrown::raw::RawTable<T,A>::find (25,879 samples, 27.28%)hashbrown::raw::RawTable<T,A>::findrust_1brc::process_chunk (66 samples, 0.07%)std::panic::catch_unwind (91,854 samples, 96.84%)std::panic::catch_unwindstd::panicking::try (91,854 samples, 96.84%)std::panicking::trystd::panicking::try::do_call (91,854 samples, 96.84%)std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once (91,854 samples, 96.84%)<core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_oncestd::thread::Builder::spawn_unchecked_::_{{closure}}::_{{closure}} (91,854 samples, 96.84%)std::thread::Builder::spawn_unchecked_::_{{closure}}::_{{closure}}std::sys_common::backtrace::__rust_begin_short_backtrace (91,854 samples, 96.84%)std::sys_common::backtrace::__rust_begin_short_backtracerust_1brc::calculate_station_values::_{{closure}} (91,854 samples, 96.84%)rust_1brc::calculate_station_values::_{{closure}}rust_1brc::process_chunk (90,753 samples, 95.68%)rust_1brc::process_chunkstd::collections::hash::map::HashMap<K,V,S>::entry (38,781 samples, 40.89%)std::collections::hash::map::HashMap<K,V,S>::entrystd::collections::hash::map::map_entry (149 samples, 0.16%)core::ops::function::FnOnce::call_once{{vtable.shim}} (91,865 samples, 96.85%)core::ops::function::FnOnce::call_once{{vtable.shim}}std::thread::Builder::spawn_unchecked_::_{{closure}} (91,865 samples, 96.85%)std::thread::Builder::spawn_unchecked_::_{{closure}}[libc.so.6] (91,929 samples, 96.92%)[libc.so.6]std::sys::pal::unix::thread::Thread::new::thread_start (91,891 samples, 96.88%)std::sys::pal::unix::thread::Thread::new::thread_startstd::sys::pal::unix::stack_overflow::imp::make_handler (26 samples, 0.03%)sigaltstack (16 samples, 0.02%)[unknown] (15 samples, 0.02%)[unknown] (13 samples, 0.01%)[unknown] (11 samples, 0.01%)[libc.so.6] (91,930 samples, 96.92%)[libc.so.6][unknown] (23 samples, 0.02%)[libc.so.6] (18 samples, 0.02%)[libc.so.6] (76 samples, 0.08%)alloc::raw_vec::RawVec<T>::with_capacity (99 samples, 0.10%)alloc::raw_vec::RawVec<T,A>::with_capacity_in (99 samples, 0.10%)alloc::raw_vec::RawVec<T,A>::allocate_in (99 samples, 0.10%)<alloc::alloc::Global as core::alloc::Allocator>::allocate (99 samples, 0.10%)alloc::alloc::Global::alloc_impl (99 samples, 0.10%)alloc::alloc::alloc (99 samples, 0.10%)malloc (94 samples, 0.10%)[libc.so.6] (2,523 samples, 2.66%)[l..[unknown] (279 samples, 0.29%)[unknown] (120 samples, 0.13%)[unknown] (108 samples, 0.11%)[unknown] (80 samples, 0.08%)[unknown] (33 samples, 0.03%)<alloc::boxed::Box<[T]> as core::convert::From<&[T]>>::from (2,631 samples, 2.77%)<a..<alloc::boxed::Box<[T]> as alloc::boxed::BoxFromSlice<T>>::from_slice (2,631 samples, 2.77%)<a..core::intrinsics::copy_nonoverlapping (2,532 samples, 2.67%)co..<std::fs::File as std::io::Read>::read (102 samples, 0.11%)read (97 samples, 0.10%)[unknown] (94 samples, 0.10%)[unknown] (87 samples, 0.09%)[unknown] (83 samples, 0.09%)[unknown] (83 samples, 0.09%)[unknown] (77 samples, 0.08%)[unknown] (46 samples, 0.05%)[unknown] (38 samples, 0.04%)[unknown] (16 samples, 0.02%)crossbeam_channel::flavors::array::Channel<T>::start_send (20 samples, 0.02%)<core::slice::iter::Iter<T> as core::iter::traits::iterator::Iterator>::position (91 samples, 0.10%)crossbeam_channel::waker::Waker::try_select::_{{closure}} (91 samples, 0.10%)crossbeam_channel::context::Context::unpark (83 samples, 0.09%)std::thread::Thread::unpark (83 samples, 0.09%)std::sys_common::thread_parking::futex::Parker::unpark (82 samples, 0.09%)std::sys::pal::unix::futex::futex_wake (80 samples, 0.08%)syscall (80 samples, 0.08%)[unknown] (79 samples, 0.08%)[unknown] (73 samples, 0.08%)[unknown] (58 samples, 0.06%)[unknown] (54 samples, 0.06%)[unknown] (48 samples, 0.05%)crossbeam_channel::waker::Waker::try_select (93 samples, 0.10%)crossbeam_channel::flavors::array::Channel<T>::write (96 samples, 0.10%)crossbeam_channel::waker::SyncWaker::notify (96 samples, 0.10%)crossbeam_channel::channel::Sender<T>::send (130 samples, 0.14%)crossbeam_channel::flavors::array::Channel<T>::send (126 samples, 0.13%)rust_1brc::calculate_station_values (2,878 samples, 3.03%)rus..all (94,853 samples, 100%)rust-1brc (94,853 samples, 100.00%)rust-1brc_start (2,879 samples, 3.04%)_st..__libc_start_main (2,879 samples, 3.04%)__l..[libc.so.6] (2,879 samples, 3.04%)[li..main (2,879 samples, 3.04%)mainstd::rt::lang_start_internal (2,879 samples, 3.04%)std..std::rt::lang_start::_{{closure}} (2,879 samples, 3.04%)std..std::sys_common::backtrace::__rust_begin_short_backtrace (2,879 samples, 3.04%)std..core::ops::function::FnOnce::call_once (2,879 samples, 3.04%)cor..rust_1brc::main (2,879 samples, 3.04%)rus.. \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 29303b2..ffcdc89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -121,57 +121,35 @@ fn calculate_station_values(mut file: std::fs::File) -> FxHashMap, Sta // Read the file in chunks and send the chunks to the processor threads let mut buf = vec![0; READ_BUF_SIZE]; - let mut unprocessed_buffer: Vec = Vec::new(); + let mut bytes_not_processed = 0; loop { - let bytes_read = file.read(&mut buf[..]).expect("Failed to read file"); - // println!("bytes_Read {:?}", bytes_read); + let bytes_read = file.read(&mut buf[bytes_not_processed..]).expect("Failed to read file"); if bytes_read == 0 { break; } - let actual_buf = &mut buf[..bytes_read]; + let actual_buf = &mut buf[..bytes_not_processed+bytes_read]; let last_new_line_index = match find_new_line_pos(&actual_buf) { Some(index) => index, None => { - // No newline found in the buffer. Store all the bytes in unprocessed_buffer - // and continue reading the file - // TODO: handle this case - unprocessed_buffer.append(&mut actual_buf.to_owned()); - continue; + println!("No new line found in the read buffer"); + bytes_not_processed += bytes_read; + if bytes_not_processed == buf.len(){ + panic!("No new line found in the read buffer"); + } + continue; // try again, maybe we next read will have a newline } }; - if bytes_read == last_new_line_index + 1 { - // If the buffer is full, then we can safely assume that the last byte is a newline - // and we can process the buffer - - if unprocessed_buffer.len() != 0 { - unprocessed_buffer.append(&mut actual_buf[..(last_new_line_index + 1)].to_owned()); - let buf_boxed = Box::<[u8]>::from(&unprocessed_buffer[..]); - sender.send(buf_boxed).expect("Failed to send buffer"); - unprocessed_buffer.clear(); - } else { - let buf_boxed = Box::<[u8]>::from(&actual_buf[..(last_new_line_index + 1)]); - sender.send(buf_boxed).expect("Failed to send buffer"); - } - } else { - // If the buffer is not full, then we can't assume that the last byte is a newline - // We need to store the bytes that are not processed in unprocessed_buffer - // and continue reading the file + let buf_boxed = Box::<[u8]>::from(&actual_buf[..(last_new_line_index + 1)]); + sender.send(buf_boxed).expect("Failed to send buffer"); - // Send chunk till last new line - if unprocessed_buffer.len() != 0 { - unprocessed_buffer.append(&mut actual_buf[..(last_new_line_index + 1)].to_owned()); - let buf_boxed = Box::<[u8]>::from(&unprocessed_buffer[..]); - sender.send(buf_boxed).expect("Failed to send buffer"); - unprocessed_buffer.clear(); - unprocessed_buffer.append(&mut actual_buf[(last_new_line_index + 1)..].to_vec()); - } else { - let buf_boxed = Box::<[u8]>::from(&actual_buf[..(last_new_line_index + 1)]); - sender.send(buf_boxed).expect("Failed to send buffer"); - unprocessed_buffer.append(&mut actual_buf[(last_new_line_index + 1)..].to_vec()); - } - } + actual_buf.copy_within(last_new_line_index+1.., 0); + // You cannot use bytes_not_processed = bytes_read - last_new_line_index + // - 1; because the buffer will contain unprocessed bytes from the + // previous iteration and the new line index will be calculated from the + // start of the buffer + bytes_not_processed = actual_buf.len() - last_new_line_index - 1; } drop(sender);