Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
CAXOPOK
1 / 1 / 0
Регистрация: 29.03.2013
Сообщений: 59
05.05.2014, 14:59     Слишком медленное чтение wstring из файла #1
Необходимо прочитать из файла некоторое количество строк(внутри них может содержаться всё что угодно: буквы цифры иероглифы). Строка представляет собой твит-сообщение вида:
[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 минуты
И что, никто не сталкивался с такой проблемой?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.05.2014, 14:59     Слишком медленное чтение wstring из файла
Посмотрите здесь:

C++ Wstring и файловый поток
Чтение из файла. Повторное чтение файла C++
C++ Запись и чтение из файла wstring
Странное поведение wstring C++
wstring to int с делемиттером C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Кудаив
328 / 405 / 24
Регистрация: 27.05.2012
Сообщений: 1,162
Завершенные тесты: 2
05.05.2014, 15:41     Слишком медленное чтение wstring из файла #2
а если попробовать в Си - стиле?
CAXOPOK
1 / 1 / 0
Регистрация: 29.03.2013
Сообщений: 59
05.05.2014, 16:00  [ТС]     Слишком медленное чтение wstring из файла #3
а по подробнее можно?
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 929
Завершенные тесты: 1
05.05.2014, 16:15     Слишком медленное чтение wstring из файла #4
А кто Вам сказал, что у Вас символ это 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;
    }
}
CAXOPOK
1 / 1 / 0
Регистрация: 29.03.2013
Сообщений: 59
05.05.2014, 16:53  [ТС]     Слишком медленное чтение wstring из файла #5
Спасибо работает, но видимо я не сразу понял причину проблемы со скоростью, ваш код на чистом чтении даёт результат около 2 минут в visual studio. Я сделал .exe вручную, через консоль и результат приблизился к 4-5 секундам на чтении файла в 1700000 строк (твитов), но сдавать это нужно на VS. Если я правильно понял, то проблема из-за байт-кода создаваемого студией. Как можно решить эту проблему?

Добавлено через 4 минуты
В string проблем с иероглифами не будет? ( китайские иероглифы, арабские шрифты)
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 929
Завершенные тесты: 1
05.05.2014, 16:56     Слишком медленное чтение wstring из файла #6
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Перечитайте понятия и термины c++ разработки, если хотите чтобы Вас понимали:
1. Ознакомтесь что такое компилятор и что такое IDE.
2. Что такое отладчик и дебаг символы (а не байт код).


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

п.с. Чтакже прочитайте что такое кодировка.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.05.2014, 17:27     Слишком медленное чтение wstring из файла
Еще ссылки по теме:

C++ Из string в wstring
Чтение файла с несколькими знаками конца файла C++
C++ Объясните, что означает wstring input = L""; и wstring output = L""; ?

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

Или воспользуйтесь поиском по форуму:
CAXOPOK
1 / 1 / 0
Регистрация: 29.03.2013
Сообщений: 59
05.05.2014, 17:27  [ТС]     Слишком медленное чтение wstring из файла #7
Учту все ваши замечания.
А ошибка моя заключалась в том, что я постоянно запускал отладчик, и это ужасно замедляло работу.
А вот и код - срабатывает за ~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. Проблема снята.
Yandex
Объявления
05.05.2014, 17:27     Слишком медленное чтение wstring из файла
Ответ Создать тему
Опции темы

Текущее время: 13:42. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru