Сейчас на форуме: jinoweb, bartolomeo (+5 невидимых) |
eXeL@B —› Программирование —› Записать / считать вектор из файла (c++) |
Посл.ответ | Сообщение |
|
Создано: 07 апреля 2017 05:57 · Поправил: Crawler · Личное сообщение · #1 Привет. Есть программа, которая читает очень много строк из файла в vector<string>. Это крайне долго. Вопрос: как записать вектор в файл так, чтобы потом его можно было тупо считать из файла одним куском в буфер памяти, а затем сделать из этого куска вектор - сразу, как со структурой, которую ты считываешь и пользуешься через указатель? С каким-нибудь char-массивом это понятно и легко, а с вектором я что-то туплю. Спасибо. ----- Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей. |
|
Создано: 07 апреля 2017 07:10 · Личное сообщение · #2 нечеткая задача которая имеет множества решений 1) не использовать вектор. написать свой оптимизированный 2) использовать вектор. заранее делая большой reverve 3) использовать вектор читая данные из памяти. а не из файла. которые предварительно туда загружены(в память) 4) написать свой аллокатор для вектора. который будет юзать к мемори мап для быстрого доступа к данным итд...фантазиям нет предела |
|
Создано: 07 апреля 2017 07:19 · Поправил: Crawler · Личное сообщение · #3 reversecode А что тут нечеткого? Нужно записать вектор в файл, а потом целиком считать его. 1) нет смысла, лучше не выйдет; 2) reserve почти не влияет на скорость процесса, проверено clock() 3) совсем не влияет на скорость, т.к. файл в современных ОС почти наверняка читается из памяти; 4) надо подумать ----- Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей. |
|
Создано: 07 апреля 2017 08:07 · Личное сообщение · #4 |
|
Создано: 07 апреля 2017 11:34 · Поправил: dosprog · Личное сообщение · #5 |
|
Создано: 07 апреля 2017 12:25 · Личное сообщение · #6 Crawler пишет: 1) нет смысла, лучше не выйдет; Лучше не выйдет, если ты напишешь такую же реализацию, но если писать под задачу, скорость вырастет на порядки. Например, можно хранить строки одним массивом, где они будут разделены нулем, а в векторе хранить только указатели на начало каждой строки. Так, выделение памяти, чтение и запись в файл будут выполняться одним вызовом апи, но после чтения нужно будет в дополнительном цикле пробежаться по массиву данных и построить массив указателей. |
|
Создано: 07 апреля 2017 12:33 · Личное сообщение · #7 rmn пишет: Лучше не выйдет Поддерживаю. Если вектор начинает упираться в скорость, нужно не решать проблему через задницу, пытаясь заставить делать vector то для чего он в принципе не предназначен. Раз данных много и появилась подобная проблема, лучше подумать о какой то мелкой базе, а не делать очередной велосипед с квадратными колесами. |
|
Создано: 07 апреля 2017 12:49 · Личное сообщение · #8 Crawler Вариант 3, который советовал reversecode. Поясню в деталях: 1. Берём файл на диске (он представляет собой набор строк, разделённых каким-нибудь \n или \r\rn) и маппим его целиком без разбора в память. 2. Читаем строки (которые пока являются const char[]) в объекты типа std::string и кладём их в вектор. 3. Анмапим файл. ----- Stuck to the plan, always think that we would stand up, never ran. |
|
Создано: 07 апреля 2017 12:58 · Личное сообщение · #9 rmn Это ничем не отличается от vector<const char* const> и не надо свое ничего писать. Вычитываем в один vector<uint8_t> и дальше мапим вектор указателей на первый. Но в таком случае если данные изменяются нужно городить свой велосипед с COW (copy-on-write). А если не изменяются проще вообще отказаться от vector<string> в пользу const char* const[]. ----- старый пень |
|
Создано: 07 апреля 2017 13:24 · Личное сообщение · #10 |
|
Создано: 07 апреля 2017 14:09 · Личное сообщение · #11 ARCHANGEL, да не повысит это производительность. Я сам тестировал это только вчера, но сильно подозревал заранее, что ничего не выйдет. Так и вышло. Наверняка реализация функции чтения так и делает. Не терзает же она жесткий диск. ----- Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей. |
|
Создано: 07 апреля 2017 14:12 · Личное сообщение · #12 |
|
Создано: 07 апреля 2017 14:19 · Личное сообщение · #13 |
|
Создано: 07 апреля 2017 17:30 · Личное сообщение · #14 |
|
Создано: 07 апреля 2017 20:23 · Поправил: Crawler · Личное сообщение · #15 Всем спасибо. Решил действительно не совсем через вектор, REVERSECODE тут оказался прав. Сначала посчитал максимально возможную длину строки из текстового файла, потом переделал файл в другой формат с фиксированной длиной строки. Если строка была меньше максимальной длины, она дополнялась нолями. То есть всё было записано в char [25]. Получившийся файл считываю в память целиком, потом создаю массив вроде такого: Code:
А потом просто создаю вектор (для удобства работы, хотя это уже на фиг не нужно): Code:
И присваиваю ему указатели на char-строки. Работает: Code:
Получилось во много раз быстрее, чем каждый раз читать строки из файла и пушить в вектор. ----- Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей. |
|
Создано: 07 апреля 2017 20:29 · Поправил: dosprog · Личное сообщение · #16 Не намного хуже была бы реализация с индексированием при предыдущем сохранении. Головняка побольше зато в разы меньше места займёт на диске.. | Сообщение посчитали полезным: Crawler |
eXeL@B —› Программирование —› Записать / считать вектор из файла (c++) |