Repository navigation
Performance Issues in Velocity #8
Description
1. Excessive Lock Contention on Hot Paths
Multiple systems use std::shared_mutex and std::mutex on frequently accessed data:
systems::entitiesusesstd::shared_mutex m_cache_mtxfor entity caching (line 204 in systems.hpp)systems::localusesstd::shared_mutex m_mtxfor snapshot access (line 246)
These locks are acquired on every frame for entity lookups and local player state checks. In a game running at 60-120+ FPS, this creates significant contention, especially when multiple subsystems (ESP, targeting, etc.) compete for reads simultaneously.
2. Unbounded Memory Growth in Material Caching
The systems::materials class maintains:
static inline std::unordered_map<std::uint64_t, std::uintptr_t> m_map{};There's no evidence of cache eviction. As players encounter new material combinations, the map grows indefinitely without cleanup, leading to memory leaks and cache misses over extended gameplay sessions.
3. Inefficient Icon/SVG Caching
The systems::icons class stores multiple caches:
std::unordered_map<icon_key, icon, icon_key_hash> m_icons{};
std::unordered_map<std::uint32_t, std::string> m_hash_to_name{};
std::unordered_map<std::string, std::vector<std::byte>> m_pending_svgs{};SVG decompilation (decompile_vsvg) happens on-demand with results stored in memory. Multiple lookups use hash computation + string comparison chains, and the icon_key_hash performs redundant hashing.
4. Repeated String Construction in Settings Initialization
In settings.hpp (lines 42-64, 134-159), initialization loops repeatedly construct strings:
for ( std::uint32_t i = 0; i < k_group_count; ++i )
{
this->groups[ i ].init( std::string( "ragebot - " ) + weapon_names[ i ] );
}This creates temporary string objects in a loop during initialization. While not on a hot path, it's wasteful.
5. Synchronous Tracing Without Result Caching
The systems::tracing class provides multiple overloaded trace() methods (lines 451-463). Each trace operation:
- Allocates a
trace_datastructure on the stack (contains 0x80 array elements) - Performs full raycasts without caching results
- Called potentially hundreds of times per frame for visibility checks, autowall calculations, etc.
No spatial partitioning or result caching is evident.
6. Input History Accumulation
The systems::input class maintains input_history_params with many fields (lines 94-120) and calls push_input_history() every frame. The underlying protobuf message proto::csgo_usercmd_pb likely accumulates history without bounds checking.
7. Unoptimized Entity Type Classification
systems::entities::classify_entity() (line 201) uses schema hash comparison but is called on every entity addition/removal. No symbol caching or hash table for schema classification is visible.
8. Redundant Configuration Serialization
The settings::changer::skin_map_field (lines 1045-1089) serializes/deserializes JSON on every config update without differential encoding. The loop at line 1075 iterates over all items and reconstructs JSON objects unnecessarily.
Recommendations
- Use lock-free data structures (atomics, concurrent queues) for frequently-read entity/player state
- Implement LRU cache eviction in material manager with max size limits
- Pre-compute icon hashes and use direct index lookups instead of nested map lookups
- Cache trace results with spatial grid acceleration for visibility checks
- Implement circular buffer for input history with fixed capacity
- Use value semantics or move semantics to reduce allocations in hot loops
Activity