Why does the this method cause lag,when I debugging here?

When I run with the commented code and comment out the red code, it doesn’t freeze

You are removing elements from the map while iterating through it, which is not allowed

if you want to do that, you can do that with an iterator instead of a for:

for (auto It = ActiveEffectHandles.CreateIterator(); It; ++It)
{
    if (TargetASC == It.Value())
    {
        TargetASC->RemoveActiveGameplayEffect(It.Key(), 1);
        It.RemoveCurrent();
    }
}
1 Like

To diagnose why the FindAndRemoveChecked method is causing lag, let’s analyze the code and consider potential performance bottlenecks:

for (auto HandlePair : ActiveEffectHandles) {
    if (TargetASC == HandlePair.Value) {
        TargetASC->RemoveActiveGameplayEffect(HandlePair.Key, 1);
        ActiveEffectHandles.FindAndRemoveChecked(HandlePair.Key);
    }
}

Potential Issues

  1. Loop Overhead:

    • If ActiveEffectHandles is a large collection, iterating over it can be time-consuming. Each iteration involves checking TargetASC == HandlePair.Value and calling RemoveActiveGameplayEffect.
  2. Frequent Removal Operations:

    • The FindAndRemoveChecked method is likely performing a search to find HandlePair.Key before removing it. If ActiveEffectHandles is implemented as a list or array, this operation could be O(n) in complexity, making the overall loop potentially O(n^2) for large datasets.
  3. RemoveActiveGameplayEffect Overhead:

    • The call to RemoveActiveGameplayEffect could be complex, involving significant processing, especially if it involves additional searches, updates, or events.

Performance Improvement Suggestions

  1. Use Efficient Data Structures:

    • Ensure that ActiveEffectHandles uses a data structure with efficient removal operations, such as a hash map or unordered set, which can provide average O(1) removal time.
  2. Batch Removal:

    • Instead of removing elements inside the loop, collect the keys to be removed and perform batch removal after the loop. This can minimize the performance impact of frequent removals:
    TArray<FActiveGameplayEffectHandle> HandlesToRemove;
    for (auto HandlePair : ActiveEffectHandles) {
        if (TargetASC == HandlePair.Value) {
            TargetASC->RemoveActiveGameplayEffect(HandlePair.Key, 1);
            HandlesToRemove.Add(HandlePair.Key);
        }
    }
    for (auto& Handle : HandlesToRemove) {
        ActiveEffectHandles.FindAndRemoveChecked(Handle);
    }
    
  3. Profile and Optimize:

    • Use profiling tools to measure the exact time spent in each part of the code. Identify the most time-consuming operations and focus optimization efforts there.
  4. Optimize Conditional Checks:

    • If possible, optimize the condition TargetASC == HandlePair.Value to reduce the time spent on comparisons.
  5. Reduce Complexity in RemoveActiveGameplayEffect:

    • Investigate the RemoveActiveGameplayEffect method to ensure it is optimized and not doing unnecessary work.

Example of a Potential Optimization

Here’s how you might refactor the code to minimize the performance impact:

TArray<FActiveGameplayEffectHandle> HandlesToRemove;
HandlesToRemove.Reserve(ActiveEffectHandles.Num()); // Preallocate memory to avoid reallocation

for (auto HandlePair : ActiveEffectHandles) {
    if (TargetASC == HandlePair.Value) {
        TargetASC->RemoveActiveGameplayEffect(HandlePair.Key, 1);
        HandlesToRemove.Add(HandlePair.Key);
    }
}

for (auto& Handle : HandlesToRemove) {
    ActiveEffectHandles.FindAndRemoveChecked(Handle);
}

In this refactored version:

  • We collect all handles to remove in a separate array.
  • After the loop, we remove all collected handles in one go, reducing the overhead of frequent removals.

By applying these strategies, you should be able to mitigate the lag caused by the FindAndRemoveChecked method.

1 Like

Thanks for your reply,It’s very useful.

Thanks for your anwsers,I solved this problem.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.