2015-08-10 2 views
5

Если кто-то может мне помочь, у меня полностью нет идей.Проблема с производительностью карт

Так у меня есть этот код (это очень упрощенная версия моего кода):

while(readNewFile()) 
{ 
    while(getNewStructFromFile()) 
    { 
     unsigned long starttime = GetTickCount(); 
     customerData.fillFromBinaryData(structPointer); 
     cout<< GetTickCount() - starttime; 

     aMap.insert(pair<int,string>(customerData.phoneNumber,"")); 
    } 

    // Ouptut all data 

    aMap.clear(); 
} 

В основном, это просто считывает запись из двоичного файла. customerData получить данные и заполнить их переменными данными из него. Затем он вставляет телефонный номер в карту (для отладки я действительно просто вставляю int и пустую строку).

Проблема заключается в том, что через короткое время эта программа будет очень медленной; если я прокомментирую вставку карты, программа работает нормально без проблем с постоянным временем выполнения для каждого файла. Если я использую вставку карты, после нескольких файлов программа снова идет очень медленно (от 8 до 10 секунд до 1 минуты и более). Но отладка с GetTickCount(), это показывает мне, что задержка происходит в customerData.fillFromBinaryData (сначала 0 мс, а затем она перескакивает до 30-40 мс (для заполнения переменных класса)). Но если я прокомментирую эту простую вставку карты, нет никакой задержки в заполнении объекта данными! Где в этом логика? Не мог бы кто-нибудь дать мне подсказку, у меня нет идей. Извините, если этот вопрос не очень хороший.

Я пробовал разные типы карт, но опять же, это показывает мне, что задержка не в вставке карты.

Редактировать/Возможное решение:

В случае, если кто имеет аналогичные проблемы, я установил VS2015, и задержка с использованием карт, нет! Я не уверен, как это связано, но Ура!

+2

Вы печатаете все данные в каждом цикле? Данные становятся все больше и больше ... – Aleksandar

+1

Я просто не могу быть единственным человеком, которому интересно, почему этот вопрос отмечен 'asn.1', учитывая, что в теле вопроса вообще нет упоминания об этом. – WhozCraig

+0

Я выводил один раз в файл, и после этого я очищаю карту, почему бы ее увеличить? customerData - это всего лишь одна запись клиента, каждый раз, когда она получает новое значение. Я действительно читаю из asn-файла :) Я не уверен, почему я добавил тег ... – Silencer

ответ

1

Может случиться так, что если карта будет очень большой, у вас возникнет проблема с управлением памятью, а fillFromBinaryData потребует некоторого распределения памяти, которое теперь медленнее. Возможно, из-за фрагментации памяти?

Я бы предложил попробовать некоторые библиотеки для этой конкретной цели. Однако я забыл, как они называются. Я просто знаю, что есть один доступный от Google, «jemalloc» или что-то подобное.

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

Еще одна вещь, возможно, - прекратить использовать карту и вместо этого использовать неупорядоченную карту. Измените сложность времени для вставки из O (logn) в O (1) с идеальной хэш-функцией, так как для вас есть номер телефона.

  • Это называется jemalloc, и это не от Google. :)
+0

Ну, первые несколько файлов карта идет нормально, как это можно объяснить? Я вызываю clear() после каждого файла, поэтому карта должна начинаться снова с 0, это не так, как будто она все еще растет? И я использую неупорядоченную карту и резервирую 4000 элементов, файл имеет около 3500 записей. – Silencer

+2

Тогда это может быть проблема фрагментации. Проверьте, что делает jemalloc. В противном случае я не знаю, что это может быть. Я бы предложил затем запустить ваше приложение с valgrind --tool = callgrind или что-то подобное. – AlexTheo