快速访问(排序的)TList

发布于 2024-12-06 06:29:29 字数 766 浏览 0 评论 0 原文

我的项目(在 Delphi 6 上运行!)需要一个内存分配列表 (TMemoryAllocation),我将其存储在一个对象中,该对象还保存有关分配大小 (FSize) 以及分配是否正在使用或空闲 (FUused) 的信息。我基本上使用它作为垃圾收集器和一种让我的应用程序始终分配/解除分配内存的方法(并且需要大量的分配/解除分配)。

每当我的项目需要分配时,它都会查找列表以找到适合所需大小的免费分配。为了实现这一点,我使用了一个简单的 for 循环:

for I := 0 to FAllocationList.Count - 1 do
begin
  if MemoryAllocation.FUsed and (MemoryAllocation.FSize = Size) then
...

我的应用程序运行的时间越长,这个列表就会增长到数千个项目,并且当我非常频繁地运行它时(每秒几次),它的速度会大大减慢。

我正在尝试找到一种方法来加速这个解决方案。我考虑过按分配大小对 TList 进行排序。如果我这样做,我应该使用某种智能方式来访问每次调用时所需的特定大小的列表。 有一些简单的方法可以做到这一点吗?

我正在考虑的另一种方法是有两个 TList。一份用于未使用的分配,一份用于已使用的分配。这意味着我必须从一个列表中提取 TList.Items 并始终添加到另一个列表中。我仍然需要使用 for 循环来浏览(现在)较小的列表。 这是正确的方法吗?

非常欢迎其他建议!

My project (running on Delphi 6!) requires a list of memory allocations (TMemoryAllocation) which I store within an object that also holds the information about the size of the allocation (FSize) and if the allocation is in use or free (FUsed). I use this basically as a GarbageCollector and a way to keep my application of allocating/deallocating memory all the time (and there are plenty allocations/deallocations needed).

Whenever my project needs an allocation it looks up the list to find a free allocation that fits the required size. To achieve that I use a simple for loop:

for I := 0 to FAllocationList.Count - 1 do
begin
  if MemoryAllocation.FUsed and (MemoryAllocation.FSize = Size) then
...

The longer my application runs this list grows to several thousand items and it slows down considerably as I run it up very frequently (several times per second).

I am trying to find a way to accelerate this solution. I thought about sorting the TList by size of allocation. If I do that I should use some intelligent way of accessing the list for the particular size I need at every call. Is there some easy way to do this?

Another way I was thinking about was to have two TLists. One for the Unused and one of the Used allocations. That would mean though that I would have to Extract TList.Items from one list and add to the other all the time. And I would still need to use a for-loop to go through the (now) smaller list. Would this be the right way?

Other suggestions are VERY welcome as well!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜清冷一曲。 2024-12-13 06:29:29

您有几种可能性:

  • 当然,使用经过验证的内存管理器,如 FastMM4 或某些 其他致力于更好地扩展多线程应用程序;
  • 重新发明轮子。

如果您的应用程序对内存分配非常敏感,也许有一些关于重新发明轮子的反馈:

  • 利用您的块大小,例如每 16 字节的倍数,然后为每个块大小维护一个列表 - 这样您就可以快速到达好的块“家族”,并赢得胜利不必将每个单独的块大小存储在内存中(如果它自己位于 32 字节列表中,则它是 32 字节块);
  • 如果需要重新分配,尝试猜测最佳的增加因子以减少内存复制;
  • 按大小对块进行排序,然后使用二分搜索,这会很多比普通的 for i := 0 to Count-1 循环更快;
  • 在列表中维护一个已删除项目的块,当您需要新项目时可以在其中查找(这样您就不必删除该项目,只需将其标记为空闲 - 如果列表很大,这会加快很多速度) ;
  • 对于项目和已释放的项目,不要使用列表(在删除或插入具有大量项目的排序项目时会出现一些速度问题),而是使用链接列表。

这绝对不是那么简单,因此您可能需要先查看一些现有代码,或者只是依赖现有的库。我认为您不必在应用程序中编写此内存分配代码,除非 FastMM4 对您来说不够快,对此我非常怀疑,因为这是一段很棒的代码!

You have several possibilities:

  • Of course, use a proven Memory Manager as FastMM4 or some others dedicated to better scale for multi-threaded applications;
  • Reinvent the wheel.

If your application is very sensitive to memory allocation, perhaps some feedback about reinventing the wheel:

  • Leverage your blocks size e.g. per 16 bytes multiples, then maintain one list per block size - so you can quickly reach the good block "family", and won't have to store each individual block size in memory (if it's own in the 32 bytes list, it is a 32 bytes blocks);
  • If you need reallocation, try to guess the best increasing factor to reduce memory copy;
  • Sort your blocks per size, then use binary search, which will be much faster than a plain for i := 0 to Count-1 loop;
  • Maintain a block of deleted items in the list, in which to lookup when you need a new item (so you won't have to delete the item, just mark it as free - this will speed up a lot if the list is huge);
  • Instead of using a list (which will have some speed issues when deleting or inserting sorted items with a huge number of items) use a linked list, for both items and freed items.

It's definitively not so simple, so you may want to look at some existing code before, or just rely on existing libraries. I think you don't have to code this memory allocation in your application, unless FastMM4 is not fast enough for you, which I'll doubt very much, because this is a great piece of code!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文