//! What one container's draw costs against the number of children it has. //! //! cargo test --release --test children_cost -- --ignored --nocapture //! //! Every other rig here varies depth, the window, or what changed between //! frames; this one varies width, which is the dimension a container's own //! per-child bookkeeping is counted in. A list of rows is the shape that gets //! wide -- a transcript, a file tree -- and a cost per child that is not flat //! down this table is a cost paid twice for every child added. //! //! Wall time rather than instructions, because what is being told apart here //! is a factor rather than a few percent, and the table says which it is: a //! flat right-hand column is linear and a rising one is not. mod rig; use iris::harness::Harness; use iris::prelude::*; use rig::env; use std::time::Instant; /// A column of leaves each with a length of its own, so the span asks every /// one of them and reads what each answered. fn build(h: &mut Harness, children: usize) -> WidgetId { let mut col = Span::empty(Dir::DOWN); for _ in 0..children { col.push( rect(Color::RED) .height(LayoutLen::px(4.0)) .add_strong(&mut h.rsc), ); } let root = col.add(&mut h.rsc); h.set_root(root); root.id() } #[test] #[ignore = "measurement, not a check"] fn draw_cost_by_children() { let frames = env("FRAMES", 40_usize); println!("{frames} full redraws of one span, per child in the last column"); for children in [100_usize, 200, 400, 800, 1600] { // Tall enough that no child is collapsed for want of room. let mut h = Harness::new((600.0, children as f32 * 8.0)); let root = build(&mut h, children); h.frame(); let start = Instant::now(); for _ in 0..frames { h.rsc.widgets_mut().mark_for_redraw(root); h.frame(); } let ms = start.elapsed().as_secs_f64() * 1000.0 / frames as f64; println!( "children {children:>5}: {ms:>8.3} ms per redraw, {:>7.4} ms each", ms / children as f64 ); } }