Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
2 / 2 / 0
Регистрация: 29.03.2013
Сообщений: 59

Слишком медленное чтение wstring из файла

05.05.2014, 14:59. Показов 1854. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Необходимо прочитать из файла некоторое количество строк(внутри них может содержаться всё что угодно: буквы цифры иероглифы). Строка представляет собой твит-сообщение вида:
[38.276866179999999, -122.03544617] 6 2011-08-28 19:03:01 I'm at Liberty Christian Center (2641 N. Texas Street, Fairfield)
Твиты могут быть многострочные. Возможно наличие ссылок, хештегов.
Её надо разбить на составные части в структуру (геолокация, время отправки, никнейм, и само сообщение) и сохранить в бинарном файле, чтоб в следующий раз (для анализа) не пришлось повторять разбиение в структуру.
Столкнулся уже сразу же с проблемой чтения.
C++
1
2
3
4
wifstream input;
input.open(nameoffile);
vector<wstring> tmp;
copy(istream_iterator<std::wstring, wchar_t, std::char_traits<wchar_t>>(input), istream_iterator<std::wstring, wchar_t, std::char_traits<wchar_t>>(),back_inserter(tmp));
Этот код вроде и работает, но работает очень медленно. Файл на ~300кб и ~2500 строк обрабатывает 30 секунд, а основная задача обработать файл 200мб на 1700000 строк, да и этот алгоритм считывает не по строкам, а разбивает по пробелам.
Изначально делал с использованием Qt, но надо это сделать с STL и не используя сторонних библиотек вроде Boost-а.
Вот что вышло в Qt
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
struct twit
{
    double x;
    double y;
    int year;
    int month;
    int day;
    int hour;
    int minuts;
    int secodns;
    QString sender;
    QString i;
};
 
void createBinaryFile(QVector<twit> & twitBase)
{
 
    QFile input(nameoffile);
    input.open(QIODevice::ReadOnly);
    QString data(input.readAll());
    input.close();
    data.remove(0,1);
    QRegExp exp("\\n\\0133");
    QStringList database = data.split(exp, QString :: SkipEmptyParts);
    twit twitBUF;
    QStringList listBuf;
    foreach(QString str, database)
    {
        listBuf = str.split(", ");
        twitBUF.x = listBuf[0].toDouble();
        listBuf = listBuf[1].split("\t");
        listBuf[0].remove(distance(listBuf[0].begin(),listBuf[0].end())-1,1);
        twitBUF.y = listBuf[0].toDouble();
        listBuf = listBuf[2].split("-");
        twitBUF.year = (listBuf[0]).toInt();
        twitBUF.month = listBuf[1].toInt();
        listBuf = listBuf[2].split(" ");
        twitBUF.day = listBuf[0].toInt();
        listBuf = listBuf[1].split(":");
        twitBUF.hour = listBuf[0].toInt();
        twitBUF.minuts = listBuf[1].toInt();
        listBuf = listBuf[2].split("\t");
        twitBUF.secodns = listBuf[0].toInt();
        listBuf = str.split("\t");
        if(listBuf[3][0] != '@')
        {
            twitBUF.sender = "NULL";
            twitBUF.i=listBuf[3];
        }
        if(listBuf[3][0] == L'@')
        {
 
            listBuf = listBuf[3].split(' ');
            listBuf[0].remove(0, 1);
            twitBUF.sender = listBuf[0];
            listBuf.removeFirst();
            str = listBuf.join(' ');
            twitBUF.i = str;
        }
        twitBase.push_back(twitBUF);
    }
    writeBinaryFile(twitBase);
}
void writeBinaryFile(QVector<twit> &twitBase)
{
    QFile output("G:/output.dat");
    output.open(QIODevice::WriteOnly);
    QDataStream stream(&output);
    stream.setVersion(QDataStream::Qt_5_2);
    foreach(twit tmp, twitBase)
    {
        stream << tmp.x << tmp.y << tmp.year << tmp.month << tmp.day << tmp.hour << tmp.minuts << tmp.secodns << tmp.sender << tmp.i;
    }
    output.close();
}
Вкратце: считываю целиком функцией input.readAll() в строку QString и потом с помощью split разбиваю в QStringList, конвертирую в числа при необходимости, заполняю структуру и добавляю её в QVector. Всё это вместе с записью в бинарный файл занимает около минуты для файла 200мб (1700000 твитов), меня такая скорость устраивала. Но как коснулось, в используя только stl и стандартные средства с++, такая схема не работает: нет ни readall(), ни split().
Подскажите пожалуйста, как хотя бы ускорить чтение до адекватных скоростей.
P.S. извиняюсь за много букв
P.P.S 1 курс, основная задача потом по координатам определить место отправления твита... И это 1 курс и срок 2 недели.

Добавлено через 1 час 40 минут
И никто ничего не подскажет?

Добавлено через 15 часов 4 минуты
И что, никто не сталкивался с такой проблемой?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.05.2014, 14:59
Ответы с готовыми решениями:

Запись и чтение из файла wstring
Всем привет! Ребята, работаю с Юникод и встал вопрос как считать из файла и записать в файл wstring name; Погуглив нашел вот...

Слишком медленное создание скриншотов
Мне нужно оптимизировать код. У меня в нескольких потоках постоянно узнается цвет конкретного пикселя на экране, но скорость вычисления...

слишком медленное перемещение frameless виджета
Собственно код дял перемещения виджета без рамки самый тривиальный: void Browser::mousePressEvent( QMouseEvent *e ) { if (...

6
419 / 418 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
05.05.2014, 15:41
а если попробовать в Си - стиле?
0
2 / 2 / 0
Регистрация: 29.03.2013
Сообщений: 59
05.05.2014, 16:00  [ТС]
а по подробнее можно?
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
05.05.2014, 16:15
А кто Вам сказал, что у Вас символ это wchar_t?

Добавлено через 1 минуту
Чтобы прочитать строку используйте std::getline(). ReadAll это пока std::getline(). Сплит тоже через std::getline().

Добавлено через 4 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//pseudo
 
std::istream& operator<<(std::istream& in, twit& t)
{
      //split here
}
 
std::vector<twit> readAll(std::fstream& fs);
{
    std::vector<twit> twits;
    
   std::string line; 
   for ( ; std::getline(fs, line); )
    { 
         std::stringstream ss(line);
         twit << ss;
    }
}
1
2 / 2 / 0
Регистрация: 29.03.2013
Сообщений: 59
05.05.2014, 16:53  [ТС]
Спасибо работает, но видимо я не сразу понял причину проблемы со скоростью, ваш код на чистом чтении даёт результат около 2 минут в visual studio. Я сделал .exe вручную, через консоль и результат приблизился к 4-5 секундам на чтении файла в 1700000 строк (твитов), но сдавать это нужно на VS. Если я правильно понял, то проблема из-за байт-кода создаваемого студией. Как можно решить эту проблему?

Добавлено через 4 минуты
В string проблем с иероглифами не будет? ( китайские иероглифы, арабские шрифты)
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
05.05.2014, 16:56
Лучший ответ Сообщение было отмечено CAXOPOK как решение

Решение

Перечитайте понятия и термины c++ разработки, если хотите чтобы Вас понимали:
1. Ознакомтесь что такое компилятор и что такое IDE.
2. Что такое отладчик и дебаг символы (а не байт код).


А теперь по делу. Вы не привели ни того как Вы компилировали, ни Ваш конечный код, ни то что Вы делали в IDE при запуске/отладке. Так что судить о скорости это очень "не правильно".

п.с. Чтакже прочитайте что такое кодировка.
1
2 / 2 / 0
Регистрация: 29.03.2013
Сообщений: 59
05.05.2014, 17:27  [ТС]
Учту все ваши замечания.
А ошибка моя заключалась в том, что я постоянно запускал отладчик, и это ужасно замедляло работу.
А вот и код - срабатывает за ~6 секунд на 17000000 строк.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<string>
#include<fstream>
#include<vector>
#include<iostream>
#include<ctime>
using namespace std;
char nameoffile[] = "G:/all_tweets.txt";
 
struct twit
{
    double x;
    double y;
    int year;
    int month;
    int day;
    int hour;
    int minuts;
    int secodns;
    string sender;
    string i;
};
 
 
void readAll(vector<string>& twits)
{
    fstream input;
    input.open(nameoffile);
 
    string line;
    int i;
    while(getline(input, line))
    {
       twits.push_back(line);
    }
    cout<<twits.size();
}
 
int main()
{
    time_t t = time(NULL);
    vector<string> alltwits;
    readAll(alltwits);
    cout << endl << "end" << ' '<< time(NULL) - t;
    system("pause");
    return 0;
}
P.S. Спасибо за советы и извините на мою неграмотность.
P.P.S. Проблема снята.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.05.2014, 17:27
Помогаю со студенческими работами здесь

Слишком медленное вычисление выражения с квадратным корнем
Код private double GetDistanceBetweenPoints(Double firstPoint, Double fithPoint) { return...

Медленное чтение
Здравствуйте,это опять снова я.В этой теме я писал про проблему раскрутки шпинделя.Слава Богу подобной проблемы больше нет.Но я появилась...

DataReader медленное чтение
Читаю данные с помощью DataReader из dbf файла - OleDbCommand commDbf = new OleDbCommand(&quot;select * from list.dbf&quot;, connExcel); ...

Медленное чтение SQLite
Добрый день. Есть приложение с базой. Одна таблица(One) на 1300 записей, id каждой записи которой является ключем примерно для 3-х...

Внешний HDD WD Elements 25A2 медленное чтение
Всех приветствую ! В наличии WD Elements 25A2 объем 1Tb, отформатирован в файловой системе HFS+, MAC его видит в дисковой утилите, но...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных через динамический список в справочнике
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru