1
0

tui_stress_test.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
  2. use dioxus::prelude::*;
  3. use dioxus_tui::{Config, TuiContext};
  4. criterion_group!(mbenches, tui_update);
  5. criterion_main!(mbenches);
  6. /// This benchmarks the cache performance of the TUI for small edits by changing one box at a time.
  7. fn tui_update(c: &mut Criterion) {
  8. let mut group = c.benchmark_group("Update boxes");
  9. // We can also use loops to define multiple benchmarks, even over multiple dimensions.
  10. for size in 1..=8u32 {
  11. let parameter_string = format!("{}", (3 * size).pow(2));
  12. group.bench_with_input(
  13. BenchmarkId::new("size", parameter_string),
  14. &size,
  15. |b, size| {
  16. b.iter(|| match size {
  17. 1 => dioxus::tui::launch_cfg(
  18. app3,
  19. Config {
  20. ..Default::default()
  21. },
  22. ),
  23. 2 => dioxus::tui::launch_cfg(
  24. app6,
  25. Config {
  26. ..Default::default()
  27. },
  28. ),
  29. 3 => dioxus::tui::launch_cfg(
  30. app9,
  31. Config {
  32. ..Default::default()
  33. },
  34. ),
  35. 4 => dioxus::tui::launch_cfg(
  36. app12,
  37. Config {
  38. ..Default::default()
  39. },
  40. ),
  41. 5 => dioxus::tui::launch_cfg(
  42. app15,
  43. Config {
  44. ..Default::default()
  45. },
  46. ),
  47. 6 => dioxus::tui::launch_cfg(
  48. app18,
  49. Config {
  50. ..Default::default()
  51. },
  52. ),
  53. 7 => dioxus::tui::launch_cfg(
  54. app21,
  55. Config {
  56. ..Default::default()
  57. },
  58. ),
  59. 8 => dioxus::tui::launch_cfg(
  60. app24,
  61. Config {
  62. ..Default::default()
  63. },
  64. ),
  65. _ => (),
  66. })
  67. },
  68. );
  69. }
  70. }
  71. #[derive(Props, PartialEq)]
  72. struct BoxProps {
  73. x: usize,
  74. y: usize,
  75. hue: f32,
  76. alpha: f32,
  77. }
  78. #[allow(non_snake_case)]
  79. fn Box(cx: Scope<BoxProps>) -> Element {
  80. let count = use_state(&cx, || 0);
  81. let x = cx.props.x * 2;
  82. let y = cx.props.y * 2;
  83. let hue = cx.props.hue;
  84. let display_hue = cx.props.hue as u32 / 10;
  85. let count = count.get();
  86. let alpha = cx.props.alpha + (count % 100) as f32;
  87. cx.render(rsx! {
  88. div {
  89. left: "{x}%",
  90. top: "{y}%",
  91. width: "100%",
  92. height: "100%",
  93. background_color: "hsl({hue}, 100%, 50%, {alpha}%)",
  94. align_items: "center",
  95. p{"{display_hue:03}"}
  96. }
  97. })
  98. }
  99. #[derive(Props, PartialEq)]
  100. struct GridProps {
  101. size: usize,
  102. }
  103. #[allow(non_snake_case)]
  104. fn Grid(cx: Scope<GridProps>) -> Element {
  105. let size = cx.props.size;
  106. let count = use_state(&cx, || 0);
  107. let counts = use_ref(&cx, || vec![0; size * size]);
  108. let ctx: TuiContext = cx.consume_context().unwrap();
  109. if *count.get() + 1 >= (size * size) {
  110. ctx.quit();
  111. } else {
  112. counts.with_mut(|c| {
  113. let i = *count.current();
  114. c[i] += 1;
  115. c[i] = c[i] % 360;
  116. });
  117. count.with_mut(|i| {
  118. *i += 1;
  119. *i = *i % (size * size);
  120. });
  121. }
  122. cx.render(rsx! {
  123. div{
  124. width: "100%",
  125. height: "100%",
  126. flex_direction: "column",
  127. (0..size).map(|x|
  128. {
  129. cx.render(rsx! {
  130. div{
  131. width: "100%",
  132. height: "100%",
  133. flex_direction: "row",
  134. (0..size).map(|y|
  135. {
  136. let alpha = y as f32*100.0/size as f32 + counts.read()[x*size + y] as f32;
  137. let key = format!("{}-{}", x, y);
  138. cx.render(rsx! {
  139. Box{
  140. x: x,
  141. y: y,
  142. alpha: 100.0,
  143. hue: alpha,
  144. key: "{key}",
  145. }
  146. })
  147. }
  148. )
  149. }
  150. })
  151. }
  152. )
  153. }
  154. })
  155. }
  156. fn app3(cx: Scope) -> Element {
  157. cx.render(rsx! {
  158. div{
  159. width: "100%",
  160. height: "100%",
  161. Grid{
  162. size: 3,
  163. }
  164. }
  165. })
  166. }
  167. fn app6(cx: Scope) -> Element {
  168. cx.render(rsx! {
  169. div{
  170. width: "100%",
  171. height: "100%",
  172. Grid{
  173. size: 6,
  174. }
  175. }
  176. })
  177. }
  178. fn app9(cx: Scope) -> Element {
  179. cx.render(rsx! {
  180. div{
  181. width: "100%",
  182. height: "100%",
  183. Grid{
  184. size: 9,
  185. }
  186. }
  187. })
  188. }
  189. fn app12(cx: Scope) -> Element {
  190. cx.render(rsx! {
  191. div{
  192. width: "100%",
  193. height: "100%",
  194. Grid{
  195. size: 12,
  196. }
  197. }
  198. })
  199. }
  200. fn app15(cx: Scope) -> Element {
  201. cx.render(rsx! {
  202. div{
  203. width: "100%",
  204. height: "100%",
  205. Grid{
  206. size: 15,
  207. }
  208. }
  209. })
  210. }
  211. fn app18(cx: Scope) -> Element {
  212. cx.render(rsx! {
  213. div{
  214. width: "100%",
  215. height: "100%",
  216. Grid{
  217. size: 18,
  218. }
  219. }
  220. })
  221. }
  222. fn app21(cx: Scope) -> Element {
  223. cx.render(rsx! {
  224. div{
  225. width: "100%",
  226. height: "100%",
  227. Grid{
  228. size: 21,
  229. }
  230. }
  231. })
  232. }
  233. fn app24(cx: Scope) -> Element {
  234. cx.render(rsx! {
  235. div{
  236. width: "100%",
  237. height: "100%",
  238. Grid{
  239. size: 24,
  240. }
  241. }
  242. })
  243. }