Что лучше в моем случае: вектор или список?

0

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

я знаю это

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

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

а также

Преимущества для перечисления контейнеров:

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

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

Должен ли я

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

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

Дополнительная информация:

Поскольку в ротации файла boost нет состояния "удалить файл, если слишком много", только "на диске достаточно свободного места", я выполнил этот этап хранения двух последних файлов или удалив самый старый каждый раз, когда новый и есть 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
    Если есть только два файла, какова цель сортировки или вообще наличия контейнера?
  • 2
    Я говорю, что разница не будет иметь большого значения, чтобы беспокоиться об этом. Вы оптимизируете то, что занимает очень мало времени. И это не так, как вы будете называть это миллиарды раз в цикле.
Показать ещё 7 комментариев
Теги:
list
sorting
vector

3 ответа

0
Лучший ответ

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

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
    это можно отсортировать? Мне нужно отсортировать его при создании
  • 1
    Я прочитал ваши новые комментарии и обновленный вопрос, и похоже, что boost::circular_buffer на самом деле не то, что вы ищете - я обновлю свой ответ. Если вы ищете всегда отсортированный контейнер, std::priority_queue может быть более подходящим. Но на самом деле, я бы лично реализовал это, поместив имена файлов в std::vector , отсортировав их с помощью std::sort , затем итерируя по первым N-2 элементам и удалив их; дело сделано. Я гарантирую вам, что перечисление и удаление файлов будет на много порядков медленнее, чем ваш выбор структуры данных.
Показать ещё 1 комментарий
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")

oh и о выборе структуры данных, вам не нужно заботиться об эффективности или проблемах производительности, я имею в виду, что вы просто индексируете 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;


}

Дополнительные замечания:

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

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

  • 1
    Если вы по какой-то причине хотите усложнить свою жизнь, добавив случайные форматы в заголовок файла журнала, например, log_iLikeRandomNames.log, попробуйте этот метод получения даты, он работает по пути, поэтому вам не нужно указывать объект File [ссылка] msdn. microsoft.com/en-us/library/...
  • 0
    Хорошее замечание. На самом деле я использовал Boost и last_write_time() , я last_write_time() свой подход. А по поводу вашего ответа я не очень согласен со сравнением строк, пример, который я добавил последним, является причиной, почему

Ещё вопросы

Сообщество Overcoder
Наверх
Меню