From 6456389eef80e60ebec8d7c26b384d3e99fbe7ac Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Wed, 14 Jun 2023 23:47:12 -0400 Subject: [PATCH] Apply performance tracing to various functions --- kifu/gtk/src/lib.rs | 11 +++ kifu/gtk/src/main.rs | 28 +++--- kifu/gtk/src/ui/board.rs | 150 ++++++++++++++++--------------- kifu/gtk/src/ui/playing_field.rs | 29 ++++-- 4 files changed, 117 insertions(+), 101 deletions(-) diff --git a/kifu/gtk/src/lib.rs b/kifu/gtk/src/lib.rs index b0ef459..94c88d6 100644 --- a/kifu/gtk/src/lib.rs +++ b/kifu/gtk/src/lib.rs @@ -19,3 +19,14 @@ impl CoreApi { }); } } + +pub fn perftrace(trace_name: &str, f: F) -> A +where + F: FnOnce() -> A, +{ + let start = std::time::Instant::now(); + let result = f(); + let end = std::time::Instant::now(); + println!("[Trace: {}] {:?}", trace_name, end - start); + return result; +} diff --git a/kifu/gtk/src/main.rs b/kifu/gtk/src/main.rs index b9a21a4..3e34e3e 100644 --- a/kifu/gtk/src/main.rs +++ b/kifu/gtk/src/main.rs @@ -1,43 +1,35 @@ use gtk::prelude::*; use kifu_core::{CoreApp, CoreRequest, CoreResponse}; use kifu_gtk::{ + perftrace, ui::{NewGame, PlayingField}, CoreApi, }; use std::sync::{Arc, RwLock}; -fn perftrace(trace_name: &str, f: F) -> A -where - F: FnOnce() -> A, -{ - let start = std::time::Instant::now(); - let result = f(); - let end = std::time::Instant::now(); - println!("[Trace: {}] {:?}", trace_name, end - start); - return result; -} - fn handle_response(api: CoreApi, window: gtk::ApplicationWindow, message: CoreResponse) { let playing_field = Arc::new(RwLock::new(None)); match message { - CoreResponse::NewGameView(view) => { + CoreResponse::NewGameView(view) => perftrace("NewGameView", || { let api = api.clone(); let new_game = NewGame::new(api, view); window.set_child(Some(&new_game)); - } - CoreResponse::PlayingFieldView(view) => { + }), + CoreResponse::PlayingFieldView(view) => perftrace("PlayingFieldView", || { let api = api.clone(); let mut playing_field = playing_field.write().unwrap(); if playing_field.is_none() { - let field = PlayingField::new(api, view); - window.set_child(Some(&field)); - *playing_field = Some(field); + perftrace("creating a new playing field", || { + let field = PlayingField::new(api, view); + window.set_child(Some(&field)); + *playing_field = Some(field); + }) } else { playing_field.as_ref().map(|field| field.update_view(view)); } - } + }), } } diff --git a/kifu/gtk/src/ui/board.rs b/kifu/gtk/src/ui/board.rs index 2940066..fa3e67d 100644 --- a/kifu/gtk/src/ui/board.rs +++ b/kifu/gtk/src/ui/board.rs @@ -1,4 +1,4 @@ -use crate::CoreApi; +use crate::{perftrace, CoreApi}; use gio::resources_lookup_data; use glib::Object; use gtk::{ @@ -83,86 +83,88 @@ impl ObjectImpl for BoardPrivate { self.drawing_area .set_draw_func(move |_, context, width, height| { - let render_start = std::time::Instant::now(); - let board = board.borrow(); + perftrace("render drawing area", || { + let render_start = std::time::Instant::now(); + let board = board.borrow(); - match background { - Ok(Some(ref background)) => { - context.set_source_pixbuf(&background, 0., 0.); - context.paint().expect("paint should succeed"); - } - Ok(None) | Err(_) => context.set_source_rgb(0.7, 0.7, 0.7), - }; - let _ = context.paint(); + match background { + Ok(Some(ref background)) => { + context.set_source_pixbuf(&background, 0., 0.); + context.paint().expect("paint should succeed"); + } + Ok(None) | Err(_) => context.set_source_rgb(0.7, 0.7, 0.7), + }; + let _ = context.paint(); - context.set_source_rgb(0.1, 0.1, 0.1); - context.set_line_width(2.); - let hspace_between = ((width - 40) as f64) / ((board.size.width - 1) as f64); - let vspace_between = ((height - 40) as f64) / ((board.size.height - 1) as f64); + context.set_source_rgb(0.1, 0.1, 0.1); + context.set_line_width(2.); + let hspace_between = ((width - 40) as f64) / ((board.size.width - 1) as f64); + let vspace_between = ((height - 40) as f64) / ((board.size.height - 1) as f64); - let pen = Pen { - x_offset: MARGIN as f64, - y_offset: MARGIN as f64, - hspace_between, - vspace_between, - }; + let pen = Pen { + x_offset: MARGIN as f64, + y_offset: MARGIN as f64, + hspace_between, + vspace_between, + }; - (0..board.size.width).for_each(|col| { - context.move_to( - (MARGIN as f64) + (col as f64) * hspace_between, - MARGIN as f64, - ); - context.line_to( - (MARGIN as f64) + (col as f64) * hspace_between, - (height as f64) - (MARGIN as f64), - ); - let _ = context.stroke(); - }); - (0..board.size.height).for_each(|row| { - context.move_to( - MARGIN as f64, - (MARGIN as f64) + (row as f64) * vspace_between, - ); - context.line_to( - (width - MARGIN) as f64, - (MARGIN as f64) + (row as f64) * vspace_between, - ); - let _ = context.stroke(); - }); - - context.set_source_rgb(0.1, 0.1, 0.0); - vec![3, 9, 15].into_iter().for_each(|col| { - vec![3, 9, 15].into_iter().for_each(|row| { - pen.star_point(context, col, row); + (0..board.size.width).for_each(|col| { + context.move_to( + (MARGIN as f64) + (col as f64) * hspace_between, + MARGIN as f64, + ); + context.line_to( + (MARGIN as f64) + (col as f64) * hspace_between, + (height as f64) - (MARGIN as f64), + ); + let _ = context.stroke(); + }); + (0..board.size.height).for_each(|row| { + context.move_to( + MARGIN as f64, + (MARGIN as f64) + (row as f64) * vspace_between, + ); + context.line_to( + (width - MARGIN) as f64, + (MARGIN as f64) + (row as f64) * vspace_between, + ); + let _ = context.stroke(); }); - }); - (0..19).for_each(|col| { - (0..19).for_each(|row| { - match board.stone(row, col) { - IntersectionElement::Filled(stone) => { - pen.stone(&context, row, col, stone.color, stone.liberties); - } + context.set_source_rgb(0.1, 0.1, 0.0); + vec![3, 9, 15].into_iter().for_each(|col| { + vec![3, 9, 15].into_iter().for_each(|row| { + pen.star_point(context, col, row); + }); + }); + + (0..19).for_each(|col| { + (0..19).for_each(|row| { + match board.stone(row, col) { + IntersectionElement::Filled(stone) => { + pen.stone(&context, row, col, stone.color, stone.liberties); + } + _ => {} + }; + }) + }); + + let cursor = cursor_location.borrow(); + match *cursor { + None => {} + Some(ref cursor) => match board.stone(cursor.row, cursor.column) { + IntersectionElement::Empty(_) => pen.ghost_stone( + context, + cursor.row, + cursor.column, + *current_player.borrow(), + ), _ => {} - }; - }) - }); - - let cursor = cursor_location.borrow(); - match *cursor { - None => {} - Some(ref cursor) => match board.stone(cursor.row, cursor.column) { - IntersectionElement::Empty(_) => pen.ghost_stone( - context, - cursor.row, - cursor.column, - *current_player.borrow(), - ), - _ => {} - }, - } - let render_end = std::time::Instant::now(); - println!("board rendering time: {:?}", render_end - render_start); + }, + } + let render_end = std::time::Instant::now(); + println!("board rendering time: {:?}", render_end - render_start); + }) }); let motion_controller = gtk::EventControllerMotion::new(); diff --git a/kifu/gtk/src/ui/playing_field.rs b/kifu/gtk/src/ui/playing_field.rs index afcb93d..74e4087 100644 --- a/kifu/gtk/src/ui/playing_field.rs +++ b/kifu/gtk/src/ui/playing_field.rs @@ -1,8 +1,17 @@ -use crate::ui::{Board, Chat, PlayerCard}; -use crate::CoreApi; +use crate::{ + perftrace, + ui::{Board, Chat, PlayerCard}, + CoreApi, +}; use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; -use kifu_core::ui::PlayingFieldView; +use kifu_core::{ + ui::{ + BoardElement, ChatElement, IntersectionElement, PlayerCardElement, PlayingFieldView, + StoneElement, TextFieldElement, + }, + Color, CoreApp, Size, +}; use std::{cell::RefCell, rc::Rc}; pub struct PlayingFieldPrivate { @@ -69,10 +78,12 @@ impl PlayingField { } pub fn update_view(&self, view: PlayingFieldView) { - self.imp().board.borrow().as_ref().map(|board| { - board.set_board(view.board); - board.set_current_player(view.current_player); - }); + perftrace("update_view", || { + self.imp().board.borrow().as_ref().map(|board| { + board.set_board(view.board); + board.set_current_player(view.current_player); + }); + }) } } @@ -82,8 +93,8 @@ pub fn playing_field_view() -> PlayingFieldView { width: 19, height: 19, }); - *board.stone_mut(4, 4) = IntersectionElement::Filled(StoneElement::new(Color::White)); - *board.stone_mut(15, 15) = IntersectionElement::Filled(StoneElement::new(Color::Black)); + *board.stone_mut(4, 4) = IntersectionElement::Filled(StoneElement::new(Color::White, None)); + *board.stone_mut(15, 15) = IntersectionElement::Filled(StoneElement::new(Color::Black, None)); *board.stone_mut(18, 18) = IntersectionElement::Unplayable; let player_card_black = PlayerCardElement { color: Color::Black,