繁体   English   中英

多选项卡地图/平铺级别编辑器中的CPU /内存效率(许多HashMaps / ArrayLists)

[英]CPU/Memory Efficiency in Multi-tabbed Map/Tile Level Editor (many HashMaps/ArrayLists)

我正在从2008年开始使用计算机进行开发,很遗憾,目前无法升级。 我确实需要在要构建的此工具中优化性能。

我的整个项目相当大,目前,我正在创建自己的地图编辑器,以供日后用于主项目的地图创建之用。 它相当简单,并且被设计为加载,保存和编辑地图拥有的“标题”数组。 它基本上是2D地图编辑器,可根据我的需求进行定制。

编辑器预览


当将地图加载到编辑器中时,其图块集(一个大的BufferedImage)被分解成每个单独的图块(具有一个较小的BufferedImage),并被加载到GUI的右侧,成为一大堆带有图标的JLabel。 我使用了各种Swing LayoutManagers来实现所需的定位。

在MapCanvas区域内,基本上完成了相同的操作。 每个图块(无论是否为空)都有一个带有图标的JLabel,已加载到网格上。 之前我曾问过有关使用Swing组件是否比使用Java2D进行设计和绘制更有效的方法,并且一致认为这并不重要(老实说,Swing可能比我写的要好得多)我)。


我相信我的问题源于我将每个JLabel及其图标互连的方式。

我的目标是减少必须创建的重复图标的数量,从理论上讲,这应该减少内存使用量和CPU使用率。 编辑器中的图块按以下方式进行交互:

  • 如果没有选择要“标记”的图块,则JLabel的图标上只会涂上一种颜色的Alpha复合图像,以表示它已被悬停,并将在MouseExit上还原
  • 如果活动的“图章”工具上有一个图块,则该图块的图像将临时替换JLabel的图标以表示它已被悬停,并将在MouseExit上还原
  • 如果活动图章工具上有一个图块,并且单击了JLabel,则除非还原,否则该JLabel的图标将被“永久”设置为活动图章图块。
  • 如果启用了“网格线”选项,则将通过ImageFactory处理每个JLabel的图标,使虚线沿顶部和左侧边缘延伸(形成网格,如图所示)。如果更改了“缩放”级别,则每个JLabel的preferredSize设置为acomodate,并且必须在ImageFactory中调整图标的大小(取决于应用网格线)


将Map加载到编辑器中后,将为其创建每个JLabel,并为其指定相应的BufferedImage(为空或不为空),并将其扔到Map的字段ArrayList中。 设置了preferredSize,以便Layout看起来正确,并将其添加到MapCanvas(这只是一个JPanel)。

我创建了各种ArrayList和HashMap对象,以便可以将JLabel作为键传递,并获取BufferedImage。 这样,当将鼠标悬停在JLabel上时,MouseEvent可以将事件的源发送回侦听器,并且可以基于接收到的JLabel捕获正确的BufferedImage。 然后,图像可以由我的ImageFactory类以上面列出的方式之一进行处理。

因此,基本上,当JLabel收到MouseEvent时,就会发生这种情况:

  • MouseEvent将源JLabel发送到ActionListener
  • 侦听器使用源JLabel作为键来获取所需的BufferedImage块
  • 然后,对BufferedImage块进行相应的处理(它可以是Alpha彩色复合材料,对其应用的Zoom因子,向其添加的网格线或它们的组合)

什么更好的方法吗? 这对我使用2年的笔记本电脑不会造成太大的损失,但是当Mouse Mouse与我的较旧台式机上的JLabel交互时,会有非常明显的滞后。

鉴于我将积极地在这两者上进行开发,因此我希望环境能够平稳运行,如果这意味着我必须严格限制内存和CPU使用率,那就可以了。

但是我似乎无法真正提出一个内存效率更高的系统。

ArrayLists和HashMaps是否有问题? 问题是很多图像操作吗?

我已经以各种方式利用了JLabel的“ setName(String)”方法(例如,每个JLabel都有一个名称,该名称包含其在JLabel的一维数组中的位置以及其在图形上的x和y坐标,即“ maptile#24:1,9”),但这需要遍历数组,而我的希望是,使用键专门抓取BufferedImages会更有效率。

Java集合是动态的,这意味着它们在添加数据时会调整大小。 它们的大小调整功能的实际模型(由ArrayList和可能的HashMap使用)类似于它们达到容量时将其容量加倍的方式,该方式包括在内存中声明一个新块并在所有存储的数据之间复制。

如果您知道每个HashMapArrayList的最大可能大小,则可以受益于使用具有初始容量的构造函数。 这里这里这将防止他们使用不必要的内存。 并且将防止任何可能的延迟而增加容量。

您还可以从每种类型的文档的前几段中受益,因为它们可以提供有效用法的良好解释(例如HashMap的loadfactor)。

考虑其他类型的List和Map(如果您不了解它们的实现方式的差异)也可能很有用,例如LinkedList删除和插入操作比ArrayList高效得多,但是随机访问要慢得多而不是ArrayList因为它必须遍历每个先前的索引才能到达所需的索引,而ArrayList可以直接访问所需的索引。

但是,很难猜测您根据这些建议进行的任何更改将有多明显。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM