Cataclysm-dda: Very slow "Use item" menu

Created on 3 Nov 2019  路  4Comments  路  Source: CleverRaven/Cataclysm-DDA

Describe the bug

Pressing 'a' for use item menu in attached save takes ~7 seconds for menu to open.

I have managed to locate what is causing the slowness.

iuse_actor.cpp:
ret_val<bool> iuse_transform::can_use( const Character &p, const item &, bool,
                                       const tripoint & ) const

line 261 currently
adding simple return on the beginning of that method makes the action almost instant

I don't know what it does exactly but I think it gathers and checks whole new inventory from all items around. And it does it for all items(?).

Steps To Reproduce

Steps to reproduce the behavior:

  1. Load attached save on build 9853 or later (game is just saved on that version,)
  2. Press 'a';

Expected behavior

It should take far less time to open that menu.

Versions and configuration

Additional context

save

(S2 - Confirmed) Performance Items / Item Actions / Item Qualities

Most helpful comment

So I tried adding a simple cache to pickup_inventory_preset::get_denial:

mutable std::unordered_map<const item*, std::string> denial_cache;

And it speeds up activation menu opening at least by half (1.1 seconds -> 0.5 seconds).

Before
image

After
image

@KorGgenT, can you evaluate this idea? I'm not sure about the lifetime of pickup_inventory_preset and whether using a cache there won't break something.

All 4 comments

That's quite a lot of items.

The attached save link is no longer available, but I can still reproduce this in 0.E-6107-g 973dd89c37

  • Use the debug menu to spawn, w item, Everything, (quantity 1).
  • Try the Eat menu - it comes up almost instantly, though it's ~12 pages long
  • Try the activate menu - it takes 15-20 seconds to generate the ~21 pages

I just took a quick look at it and something looks suspicious:
Character::can_pickVolume(item const&, bool) is called five times in different places (I assume for the same items).

image
image

Can somebody who's more familiar with item management check that out?

So I tried adding a simple cache to pickup_inventory_preset::get_denial:

mutable std::unordered_map<const item*, std::string> denial_cache;

And it speeds up activation menu opening at least by half (1.1 seconds -> 0.5 seconds).

Before
image

After
image

@KorGgenT, can you evaluate this idea? I'm not sure about the lifetime of pickup_inventory_preset and whether using a cache there won't break something.

Was this page helpful?
0 / 5 - 0 ratings