Подтвердить что ты не робот

Более быстрый способ очистки boost:: interprocess:: map?

У меня есть приложение, которое использует boost::interprocess::map в общей памяти. Карта содержит большое количество элементов (от 100 к до 10 М), и все работает очень хорошо, за одним исключением: необходимо периодически очищать карту, и это, по-видимому, занимает около 4 мкс на элемент (что в худшем случае 40 секунд), что неприемлемо для приложения. Похоже, что clear() фактически удаляет каждый элемент карты отдельно и ребалансирует дерево после каждого удаления, поэтому он ужасно неэффективен, когда у вас есть большое количество элементов. В идеале clear() просто удалил бы все элементы без какого-либо перебалансирования - можно ли каким-либо образом реализовать такой оптимизированный метод clear()?

(Кстати, я также пробовал boost:interprocess:flat_map - это намного быстрее, чем можно было ожидать (в 10 раз быстрее), но это слишком медленно для операций вставки/удаления.)

Примечание. qaru.site/info/309499/... затронул аналогичную проблему с меньшими картами STL в нормальной (то есть не общей) памяти, но на самом деле не решила проблему.

4b9b3361

Ответ 1

От взгляда на код Boost, я предполагаю, что у вас есть:

  • Обнаружена ошибка при реализации rbtree

или

  • Кодирование с использованием безопасного режима или автоматической отмены

От\boost_1_54_0\boost\intrusive\rbtree.hpp

   //! <b>Effects</b>: Erases all of the elements.
   //!
   //! <b>Complexity</b>: Linear to the number of elements on the container.
   //!   if it a safe-mode or auto-unlink value_type. Constant time otherwise.
   //!
   //! <b>Throws</b>: Nothing.
   //!
   //! <b>Note</b>: Invalidates the iterators (but not the references)
   //!    to the erased elements. No destructors are called.
   void clear()
   {
      if(safemode_or_autounlink){
         this->clear_and_dispose(detail::null_disposer());
      }
      else{
         node_algorithms::init_header(this->priv_header_ptr());
         this->priv_size_traits().set_size(0);
      }
   }

В комментарии здесь четко указано, что вы можете получить постоянный тайм-аут из реализованной ясности. Пейджинг через код повышения, мое чтение заключается в том, что interprocess:: map в конечном итоге использует этот rbtree в качестве базовой структуры данных. Я не заметил, что были установлены безопасные или автоматические развязки, но я мог пропустить это. Если вы установили один из них, я бы сначала посмотрел, смогу ли я жить без него, и если да, то проблемы с производительностью, надеюсь, уйдут.

Если это ошибка в boost, вам придется обойти это. Я бы сразу сообщил об этом, используя контактную информацию в заголовке:

/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga  2006-2012
//
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////

У быстрого поиска Google есть контактные данные для Ion по адресу:

http://boost.2283326.n4.nabble.com/template/NamlServlet.jtp?macro=user_nodes&user=161440

Или, перейдя в http://www.boost.org/development/bugs.html

И затем реализуйте решение Paul R или rileyberton в зависимости от вашего уровня производительности.