Блог пользователя KonanMentor

Автор KonanMentor, 10 лет назад, По-русски

Решил задачу 427D - Расшифровка сигнала с помощью суффиксного дерева. Однако мое решение за O(N) (6579114) работало дольше, чем решения за O(n2) — 717 мс и кушало ~200 мб памяти!

Сразу нашелся тест, на котором локально это решение работало долго (около 5,8 секунды!!!):

aaa...aa

aaa...aa

Стал разбираться. Выяснилось, что по ходу построения дерева, создается ~12,5 млн. позиций в дереве (объект, который указывает на вершину в сжатом боре). Эти объекты я создавал в куче, через new. Это удобно тем, что можно вернуть указатель на NULL (например, при попытке перехода из вершины по символу).

Я, конечно, знал, что выделение памяти в куче работает дольше, чем на стеке, но не в 15 же раз! :) Вообще, изначально я хотел избавиться от new из-за лишнего потребления памяти: в каждой позиции хранится указатель на вершину(4 байта) + номер буквы на ребре(4 байта) * 12,5 млн.  ≈  100 мб.

В итоге без использования new мое решение получило AC (6579111) за 171 мс, при этом потребляя 2 мб памяти.

У меня только 2 вопроса:

Почему 200 - 100 = 2

И почему локальное время выполнения так сильно отличается от серверного(без new стало работать быстрее на 1 секунду, но 4,8 и 0,17 — все же большая разница)

Заранее спасибо

  • Проголосовать: нравится
  • +13
  • Проголосовать: не нравится

»
10 лет назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится

Почему 200 - 100 = 2

Погуглите про такую вещь, как менеджер памяти. Именно он и отжирает дополнительные 100МБ для своей работы.

И почему локальное время выполнения так сильно отличается от серверного(без new стало работать быстрее на 1 секунду, но 4,8 и 0,17 — все же большая разница)

Вероятно, локально Вы компилируете решение без оптимизации. Добавьте ради интереса флаг -O2 и сравните результат.

Оффтопик: Вы пользуетесь FAR'ом, не так ли?

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится

    Оффтоп: А почему на всех олимпиадах компалят именно с О2, а не с О3?

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Погуглил. Походу, минимальный размер выделяемой через new памяти равен 16 байтам.

    Провел тест: создал 107 char'ов (размер 1 байт) и столько же структур размером 8 байт. Оба варианта захавали 156 мб  ≈  . Теперь понятно, откуда разница в 2 раза.

    Я был уверен, что компилирую с оптимизацией, но действительно флага -O2 не было. Спасибо!

    P.S. Нет, FAR'ом не пользуюсь.