现在,第一条规则始终是“不要过早优化”。您需要确保您需要对更简洁的代码进行优化。
现在,在人生游戏中,您最初看到的是一个相当空的屏幕。然而,随着游戏的进行,越来越多的单元格会被填满,最终会填满整个棋盘。现在 GOL 规则规定这些单元中的大多数将从一个周期变为另一个周期。
您还需要了解“使”区域“无效”的含义。在 Windows 中,无效区域“加起来”形成“更新区域”,因此 WM_PAINT 消息可以告诉程序要绘制屏幕的哪些部分。在您的 Paint 事件处理程序中,您使用RectVisible
来确定是否要刷新单元格。
换句话说,执行方法 1 的“成本”(假设板尺寸 n):
(n x n) x (redraw cell + update cell on screen)
请注意,我假设您在绘制单元格之前记得做一个清晰的屏幕,否则在最后一个周期中曾经“活着”的单元格将留在屏幕上。因此,这假设您在整个屏幕上绘制一个活单元格或一个空白单元格。
做方法2的“成本”:
(v) x (redraw cell + update cell on screen) + (n x n) x (RectVisible call)
其中 v = 更改的单元格数(请参阅下面的警告说明)。
因此,在以下情况下,方法 1 比方法 2 更快:
(n x n) x redraw < v x redraw + (n x n) x RectVisible
n2 x (redraw - RectVisible) < v x redraw
v > ((redraw - RectVisible) / redraw) x n2
v > (1 - RectVisible/redraw) x n2
换句话说,更改单元格的数量必须大于一减去(RectVisible 成本/重绘成本)的比率。现在,RectVisible
与在屏幕上绘制位图相比,它通常非常快,尤其是在您的单元格具有高分辨率的情况下。因此,Rectvisible/redraw 通常是一个非常小的数字,只有当有超过 99% 的板同时发生变化时,方法 1 才比方法 2 更快,这是不太可能的。
换句话说,您会发现方法 2 通常会产生更高的性能,因为DrawImage
如果要在剪切区域之外(即不在更新区域内)绘制图像,通常会跳过整个操作。
警告 - 您的代码无法正常工作
但是,您在方法 2 中的代码将不起作用。您必须记住在上一个周期中“清除”曾经有“活”细胞的“死”细胞。换句话说,您使“更改”的单元格无效,而不仅仅是那些“活着”的单元格。多个周期“活着”的细胞不需要失效。因此,您的方法中的逻辑MyInvalidate
是有缺陷的。