У меня есть некоторый код, который использует рекурсию в своей реализации. Профилировщик , который я использую , не справляется с рекурсивными вызовами функций, поэтому я хотел бы переписать его как нерекурсивный.
Текущий код выглядит примерно так:
void Parse(Foo foo)
{
A()
for (;;)
{
B();
if (C())
return;
if (D())
{
Run();
}
E();
}
}
void Run()
{
X();
if (Y())
{
Parse();
}
Z();
}
Выше приведен псевдокод. Буквы A, B, C, D, E, X, Y и Z являются методами, а также Parse () и Run (). Для простоты я пропустил различные параметры и разыменования объектов (например, Run - это метод экземпляра объекта, и он принимает некоторые параметры).
В любом случае, мой вопрос: как мне превратить это в нерекурсивный код?
Мне кажется, что эквивалентный нерекурсивный код:
void Parse(Foo foo)
{
//create a local stack variable to emulate recursion
Stack<Foo> foos = new Stack<Foo>();
foos.Add(foo());
start_subroutine:
A()
for (;;)
{
B();
if (C())
{
//instead of returning from a recursive call
if (foos.Count > 1)
{
foo = foos.Pop();
goto end_subroutine;
}
return;
}
if (D())
{
//instead of invoking Run as a subroutine, bring its functionality inline
//Run();
X();
if (Y())
{
//instead of calling self recursively
//Parse();
//push onto a local stack variable and jump
foos.Add(foo);
goto start_subroutine;
}
end_subroutine:
Z();
}
E();
}
}
Я в порядке, но я не вижу, как это сделать без использования goto; и я не помню, чтобы когда-нибудь кто-нибудь писал, что это один из тех случаев, когда необходимо перейти на следующую страницу.