В более быстром варианте вот тут за константное время проверка делается.
if (track.ContainsKey(chest))
{
yield return track[chest];
continue;
}
У тебя она сделана через цикл:
for (int i = 0; i < chests.Length; i++)
{
if (point.Value.Equals(chests[i]))
{
yield return point;
}
}
Если я не туплю, и эти куски действительно делают одно и то же.
А вообще более детально разобраться в причинах низкой скорости ты можешь:
1. При помощи бенчмарков (гугли BenchmarkDotNet)
2. Посмотрев на листинг кода, который генерирует компилятор (смотри sharplab)
3. Путём профайлинга - посмотри на dotmemory и dottrace