Инструмент для обнаружения ненужных рекурсивных вызовов в программе?

Очень распространенная ошибка новичков при написании рекурсивных функций - это случайное отключение полностью избыточных рекурсивных вызовов одной и той же функции. Например, рассмотрим эту рекурсивную функцию, которая находит максимальное значение в двоичном дереве (не в двоичном дереве поиска):

int BinaryTreeMax(Tree* root) {
    if (root == null) return INT_MIN;

    int maxValue = root->value;
    if (maxValue < BinaryTreeMax(root->left))
        maxValue = BinaryTreeMax(root->left);   // (1)
    if (maxValue < BinaryTreeMax(root->right))
        maxValue = BinaryTreeMax(root->right);  // (2)

    return maxValue;
}

Обратите внимание, что эта программа потенциально делает два полностью избыточных рекурсивных вызова BinaryTreeMax в строках (1 ) и (2). Мы могли бы переписать этот код так, чтобы не было необходимости в этих дополнительных вызовах, просто кэшируя значение из предыдущего:

int BinaryTreeMax(Tree* root) {
    if (root == null) return INT_MIN;

    int maxValue = root->value;
    int leftValue = BinaryTreeMax(root->left);
    int rightValue = BinaryTreeMax(root->right);

    if (maxValue < leftValue)
        maxValue = leftValue;
    if (maxValue < rightValue)
        maxValue = rightValue;

    return maxValue;
}

Теперь мы всегда делаем ровно два рекурсивных вызова.

У меня вопрос, есть ли инструмент, который выполняет статический или динамический анализ программы (на любом языке, который вам нравится; я не слишком разборчив!), Который может определить, делает ли программа совершенно ненужную рекурсивную звонки. Под «совершенно ненужным» я подразумеваю, что

  1. рекурсивный вызов был сделан раньше,
  2. тем же вызовом рекурсивной функции (или одного из ее потомков), и
  3. сам вызов не имеет наблюдаемой стороны - последствия.

Это то, что обычно можно определить вручную, но я думаю, было бы здорово, если бы существовал какой-нибудь инструмент, который мог бы автоматически отмечать такие вещи, чтобы помочь студентам получить обратную связь о том, как избежать простых, но дорогостоящих ошибок. в их программах, что может привести к огромной неэффективности.

Кто-нибудь знает о таком инструменте?

8
задан GEOCHET 10 August 2015 в 16:40
поделиться