Перейти к содержанию

ЛР 6. Сравнение производительности

Тема: Бенчмарк рекурсивного и итеративного построения дерева с визуализацией

Цель работы

Сравнить время построения бинарного дерева рекурсивным и итеративным методами. Построить графики с помощью matplotlib.

Задание

  • Реализовать рекурсивную и итеративную функции построения дерева.
  • Написать функцию бенчмарка с использованием timeit.
  • Построить график зависимости времени от высоты дерева.

Код

import timeit
import matplotlib.pyplot as plt
from typing import Callable, List


def build_tree_recursive(height, root,
                         left_branch=lambda x: x * 2 + 1,
                         right_branch=lambda x: 2 * x - 1):
    if height <= 0:
        return []
    return [
        root,
        build_tree_recursive(height - 1, left_branch(root), left_branch, right_branch),
        build_tree_recursive(height - 1, right_branch(root), left_branch, right_branch)
    ]


def build_tree_iterative(height, root,
                         left_branch=lambda x: x * 2 + 1,
                         right_branch=lambda x: 2 * x - 1):
    if height < 1:
        return []
    tree = [root, [], []]
    current_level = [tree]
    level = 1
    while level < height:
        next_level = []
        for node in current_level:
            left_node = [left_branch(node[0]), [], []]
            right_node = [right_branch(node[0]), [], []]
            node[1] = left_node
            node[2] = right_node
            next_level.extend([left_node, right_node])
        current_level = next_level
        level += 1
    return tree


def benchmark(func, heights, root=9, number=10, repeat=3):
    results = []
    for h in heights:
        times = timeit.repeat(lambda: func(h, root), number=number, repeat=repeat)
        results.append(min(times))
    return results


def main():
    ROOT = 9
    HEIGHTS = list(range(1, 7))

    recursive_times = benchmark(build_tree_recursive, HEIGHTS, root=ROOT)
    iterative_times = benchmark(build_tree_iterative, HEIGHTS, root=ROOT)

    for h, r, i in zip(HEIGHTS, recursive_times, iterative_times):
        print(f"Высота {h}: рекурсивно = {r:.6f}s, итеративно = {i:.6f}s")

    plt.plot(HEIGHTS, recursive_times, label="Рекурсивная")
    plt.plot(HEIGHTS, iterative_times, label="Итеративная")
    plt.xlabel("Высота дерева")
    plt.ylabel("Время построения (сек)")
    plt.title("Сравнение рекурсивного и итеративного построения дерева")
    plt.legend()
    plt.grid(True)
    plt.show()

if __name__ == "__main__":
    main()

Выводы

При небольших высотах дерева (1–3) разница между рекурсией и итерацией минимальна. С увеличением высоты итеративный метод показывает преимущество за счёт отсутствия накладных расходов на стек вызовов. Визуализация с matplotlib наглядно подтверждает эту тенденцию.