2014-12-04 2 views
0

У меня есть функция, которая читает файлы в папке (я использую boost для этого). Я также пытаюсь сохранить только 2 файла (они являются файлами журналов, поэтому они вращаются, и я не хочу сохранять старые журналы = журналы в третьем файле). Я храню имена файлов в списке, но поскольку чтение не выполняется во временном порядке создания, мне нужно отсортировать список.Что лучше в моем случае: вектор или список?

Я знаю, что

векторы хороши:

  • Доступ к отдельным элементам по их позиции индекса (постоянная времени).
  • Итерация по элементам в любом порядке (линейное время).
  • Добавить и удалить элементы с его конца (постоянное время амортизации).

и

Преимущество в список контейнеров:

  • Эффективная вставка и удаление элементов в любом месте в контейнере (постоянное время).
  • Эффективные движущиеся элементы и блок элементов внутри контейнера или даже между различными контейнерами (постоянное время).
  • Итерация по элементам в прямом или обратном порядке (линейное время).

Я не уверен, что это лучший способ сделать это: используя список или вектор?

Должен ли я

  • использование вектора и отсортировать его по возрастанию, удалить с конца, добавить новый элемент (в конце), порядок и т.д.; или
  • используйте список и отсортируйте его по возрастанию, удалите с самого начала, добавьте новый элемент в конец, курорт и т. Д .;

  • сортирует нужно только в самом начале, потому что каждое имя файла, вставить последний созданный?
  • Если список/вектор отсортирован, какое время прибегать к нему?
  • Если я использую std::is_sorted, это нормально, если вы не сортируете каждый раз?

Некоторые подробнее:

Поскольку вращение файла наддува не имеет «удалить файл, если слишком много» состояние, только «есть достаточно места на диске», у меня есть реализовал этот шаг хранения последних двух файлов или удалив старейший каждый раз, когда создается новый, и есть 2 файла журналов. Поэтому каждый раз, когда создается новый файл журнала, я проверяю список файлов, и если их достаточно (2 или более), просто удалите старые (ые) файлы. Поскольку имена файлов являются logs_%N.log, я не могу знать, если файл logs_X1.log старше logs_X2.log

например: перезапустить приложения, есть файлы logs_51.log, logs_52.log, что один собирается быть удалены? Предположим, что он собирается удалить logs_51.log и создать logs_0.log, если я его снова заново запустил, будут logs_52.log и logs_0.log. Какой из них будет удален сейчас?)

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

+2

Если есть только два файла, какая цель сортировки или даже наличие контейнера? – dasblinkenlight

+2

Я говорю, что разница не имеет значения, чтобы беспокоиться об этом. Вы оптимизируете то, что занимает очень мало времени. И это не так, как вы будете называть это миллиарды раз в цикле. – drescherjm

+0

'использовать векторный и отсортировать его по возрастанию, удалить из конца, добавить новый элемент (в конце), изменить порядок и т. Д., Не имеет смысла. Вставка в начале выполняется намного быстрее, чем вставка и сортировка. – user2079303

ответ

0

На самом деле я использовал подталкивание для сортировки файлов в последней измененной форме:

bool Logger::compareAccessTime(const std::string& path1In, const std::string& path2In) 
{ 
    return (fs::last_write_time(fs::path(path1In)) < fs::last_write_time(fs::path(path2In))); 
} 

где fs = boost::filesystem

И потому, что я использовал список строк, я не изменил весь код, но добавил list::sort(compareAccessTime) при инициализации списка. Мне это нужно только в начале приложения, потому что тогда я добавляю в конец и удаляю с начала.

3

Для этого конкретного случая, когда контейнер будет иметь ~ 2 элемента, это не имеет значения, один маленький бит. Время, затрачиваемое на перечисление файлов и удаление их, будет на несколько порядков медленнее, чем ваш выбор алгоритма и структуры данных. Просто поместите имена файлов в std::vector, используйте std::sort (который сортирует ваши имена файлов журналов, чтобы первые были на первом месте), а затем удалите первые элементы N-2. Работа выполнена.

Но для некоторых общих рекомендаций:

В эти дни общий совет, кажется, что std::vector лучше std::list даже для многих вещей std::list, кажется, это было бы хорошо, главным образом благодаря тому, что это смежное хранению который более удобен для кэширования.

Можно построить тесты, которые будут показывать std::list быстрее, но вы не ошибетесь, если вы выберете std::vector за все!

Если вам нужно поддерживать контейнер с течением времени и всегда нужно иметь возможность удалить самый маленький/самый большой элемент, то может быть хорошей идеей std::priority_queue.

Если вам нужно найти N наименьших/наибольших предметов в контейнере, std::partial_sort - алгоритм для этого; он будет быстрее, чем полный std::sort, потому что он не тратит усилий на сортировку элементов, которые вам не нужны.

Но, как и в случае с такими вопросами общей производительности, единственный правильный ответ должен быть «попробовать и увидеть», я боюсь!

Редактировать: Первоначально я предлагал boost::circular_buffer, так как это то, о чем говорила проблема, но теперь ясно, что это нехорошее предложение, так как упорядочение должно быть создано путем сортировки, а не путем вставки.

+0

он может быть отсортирован?Мне нужно отсортировать его при его создании. – sop

+1

Я прочитал ваши новые комментарии и обновленный вопрос, и похоже, что 'boost :: circ_buffer' на самом деле не тот, который вы ищете, - я обновлю свой ответ. Если вы ищете всегда отсортированный контейнер, более вероятным может быть 'std :: priority_queue'. Но на самом деле, я бы лично реализовал это, поместив имена файлов в 'std :: vector', отсортировал их с помощью' std :: sort', затем перебирал первые N-2 и удалял их; Работа выполнена. Я гарантирую, что перечисление и удаление файлов будет на несколько порядков медленнее, чем ваш выбор структуры данных. –

+1

Также ... серьезно, не беспокойтесь об этом, но если вы столкнулись с ситуацией, когда вам нужно выбрать N самых маленьких/самых больших предметов из контейнера, и вам нужно сделать это быстро, алгоритм для этого может be 'std :: partial_sort' - он не будет тратить время на сортировку частей контейнера, которые вам не нужно сортировать. Честно говоря, хотя для этой проблемы это больше проблем, чем того стоит. –

0

Никто здесь на самом деле не получает его, парень должен сравнить имя 2-файлов, а не уроки структуры данных

использовать строку :: сравнить сравнить файлы, да будет сравнить эти цифры в конце ваши логах тоже, так что не беспокойтесь о том, что

Вот как это работает

value=String.Compare(filenameA,filenameB) 



    If value<0 then print("filenameA is smaller than filenameB") 
    If value>0 then print("a is bigger than b") 
    If value=0 then print("a equals b") 

ой и о выборе структуры данных, вам не нужно заботиться об эффективности или производительности вопросы я имею в виду вы просто exing 2 файла по имени простой и скромный массив будет делать трюк

здесь в пример о том, как это сделать

putNewFileMethod(FileType* arrayofFiles,FileType MynewFile)` 
{ 



String nameOfFile0=arrayOfFiles[0].method_that_retrieves_the_filename(); 
String nameOfFile1=arrayOfFiles[1].method_that_retrieves_the_filename();//you can search for a method of this kind in the docs of the api you are using,` 

int value=String.Compare(nameOfFile0,nameOfFile1); 

     If(value<0) 
     arrayOfFiles[0]=MynewFile; 
else arratOfFiles[1]=MynewFile; 


} 

дополнительные примечания:

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

Структуры данных не приходит с Buildin функции сортировки, по крайней мере, большинство из них, так что вы просто должны сделать одну из вашей собственной личности

+1

Если вы по какой-то причине хотите сделать вашу жизнь более сложной, добавив случайные форматы в заголовок файла журнала, например log_iLikeRandomNames.log, попробуйте этот метод извлечения даты, он работает по пути, поэтому вам не нужно предоставлять объект File [link] http : //msdn.microsoft.com/en-us/library/system.io.file.getcreationtime (v = vs.110) .aspx –

+0

Хорошее замечание. На самом деле я использовал функцию Boost и 'last_write_time()', я отправлю свой подход. И о вашем ответе, я действительно не согласен с сопоставлением строк, примером того, что я добавил последнее, является причина, почему – sop

Смежные вопросы