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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
iiieoi
Заблокирован
#1

Очень медленное выполнение .c_str() в minGW - C++

02.08.2015, 18:45. Просмотров 416. Ответов 15
Метки нет (Все метки)

Есть функция:
C++
1
sscanf(line.c_str(), "%d\t%d\t%hu.%hu.%hu\t%hu:%hu:%hu\t%lf", &tmpData.Pip, &tmpData.Tm, &tmpData.Year, &tmpData.Mont, &tmpData.Day, &h, &tmpData.Min, &tmpData.Sec, &tmpData.Spd);
line типа string;

Время обработки 6кк таких строк:
MinGW - 34c
Cygwin - 11c

запускаю с ключами -O3 -std=c++11

Кто подскажет почему MinGW так тормозит на .c_str(), с чем это может быть связано?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2015, 18:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Очень медленное выполнение .c_str() в minGW (C++):

MinGW очень раздувает код - C++
Всем привет! Скачал MinGW и был очень неприятно удивлён: после компиляции исполняемый файл программы получался 485 кб, а та же самая...

Может ли MinGW x64 компилить приложения x32? Или нужно для этого отдельно ещё MinGW х32 качать? - C++
Просто решил поиграться с CodeLite.

Mingw-w64 MinGW TDM-GCC - C++
Всем привет. Хочу понять, существует ли принципиальная разница между Mingw-w64, MinGW и TDM-GCC? Какие плюсы/минусы у этих трех...

string, c_str - C++
функция string.c_str() возвращает const char*, что бы не изменяли строку напрямую. Но! Если явно преобразовать указатель к char*, то строка...

Не работает преобразование с c_str() - C++
Доброго времени суток. Пытаюсь определить расширение найденного файла путем сравнения со строкой: if(NULL !=...

X=atof(s.c_str()); - ошибка в Builder10 - C++
Здравствуйте ! Помогите, пожалуйста, чайнику. Проблема такая: Создаю учебный проект простого калькулятора. Обработчик щелчка по...

15
Croessmah
Эксперт CЭксперт С++
13409 / 7559 / 853
Регистрация: 27.09.2012
Сообщений: 18,601
Записей в блоге: 3
Завершенные тесты: 1
02.08.2015, 19:00 #2
Для начала:
21.4.7 basic_string string operations
21.4.7.1 basic_string accessors


C++
1
2
const charT* c_str() const noexcept;
const charT* data() const noexcept;
1. Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
2. Complexity: constant time.
3. Requires: The program shall not alter any of the values stored in the character array.
0
iiieoi
Заблокирован
02.08.2015, 19:21  [ТС] #3
да, я ошибся, попробовал читать файл через fgets а не через getline, всеравно результаты по времени такие же.

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

110970 20000 2015.06.08 09:01:10 1
110960 35000 2015.06.08 09:01:45 1.1
110950 20000 2015.06.08 09:02:05 1.3
где данные хранятся в виде шаблона: <int>/t<int>/t<int>.<int>.<int>/t<int>:<int>:<int>/t<double> каждое из значений которого сохраняется в массив структур.
0
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,287
Завершенные тесты: 3
02.08.2015, 20:27 #4
iiieoi, перегрузить операцию ввода для класса, который будет содержать переменные для каждой составляющей строки:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class some
{ 
  int one, two, three, four...;
  istream& operator>>(istream& is)
  {
     is >> one >> two >> three;
     is.ignore();
     is >> five;
     ...
     return is;
   }
  ...
};
Разумеется, перегрузка должна быть глобальной дружественной к классу функцией, ну, думаю, разберетесь.
1
iiieoi
Заблокирован
02.08.2015, 20:54  [ТС] #5
tnk500, спасибо за вариант, но по опыту знаю что потоки это далеко не самый быстрый способ.
0
S_el
2106 / 1625 / 308
Регистрация: 15.12.2013
Сообщений: 6,483
02.08.2015, 21:05 #6
iiieoi, довольно быстрый если грамотно использовать.
https://habrahabr.ru/post/246257/
0
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,287
Завершенные тесты: 3
02.08.2015, 21:11 #7
iiieoi, что, даже std::ios::sync_with_stdio(0) не улучшает вашего мнения о потоках?
0
iiieoi
Заблокирован
03.08.2015, 00:15  [ТС] #8
Нет, флаг не помогает, в моем случае sscanf оказывается быстрее потоков процентов на 30 по времени.

И непонятно почему код из MinGW почти в три раза медленнее чем Cygwin.
Хотя при работе с vector и list он примерно раза в три быстрее чем Cygwin.

Добавлено через 9 минут
Попробовал загрузку файла запихнуть в dll и скомпилировать Cygwin, а ядро, где будет происходить обработка данных MinGW. В результате программа не может даже строку с именем файла передать в функцию внури dll. Хотя если и само ядро компилировать тоже в Cygwin то проблем не возникает. Это глюк такой или так и должно происходить?

P.S. среда разработки codeblocks, ОС Win7
0
DrOffset
7310 / 4406 / 998
Регистрация: 30.01.2014
Сообщений: 7,242
03.08.2015, 00:58 #9
Цитата Сообщение от iiieoi Посмотреть сообщение
В результате программа не может даже строку с именем файла передать в функцию внури dll
Как эта передача происходит?

Добавлено через 52 секунды
Цитата Сообщение от iiieoi Посмотреть сообщение
Это глюк такой или так и должно происходить?
Скорее всего это происходит из-за различий в ABI и разных библиотек времени исполнения (runtime library) на стороне dll и приложения.

Добавлено через 17 минут
Цитата Сообщение от iiieoi Посмотреть сообщение
попробовал читать файл через fgets а не через getline, всеравно результаты по времени такие же.
Так может сразу fscanf попробовать?
C++
1
fscanf(file, "%d\t%d\t%hu.%hu.%hu\t%hu:%hu:%hu\t%lf", &tmpData.Pip, &tmpData.Tm, &tmpData.Year, &tmpData.Mont, &tmpData.Day, &h, &tmpData.Min, &tmpData.Sec, &tmpData.Spd);
И во временную строку читать не надо будет.
1
iiieoi
Заблокирован
03.08.2015, 13:11  [ТС] #10
DrOffset, спасибо за подсказку про fscanf, действительно использовал С++ и не подумал про С, попробую как приду с работы

а передача происходит так:
программа
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
#include <windows.h>
#include <vector>
 
struct Data{
    int a,
        b,
        c;
};
 
main()
{
    HINSTANCE h;
    vector <Data> vectData; 
    int (*DllFunc) (string * str, vector <Data> * vect);
    h=LoadLibrary("C:\\Project\\test\\ofile.dll");
    string file = "C:\\tt.txt";
    
    if (h) {
        DllFunc=(int (*) (string * str, vector <Data> * vect))GetProcAddress(h,"OpenDataFile");
        if (DllFunc) {
            int n = DllFunc(&file,&vectData);
        };
    };
    FreeLibrary(h);
};
функция загрузки в dll
C++
1
2
3
4
int DLL_EXPORT OpenDataFile(const string * fn, vector <Data> * vectD)
{
    cout >> *fn >> endl;
}
ну и как я и говорил, при использовании одного компилятора и для dll и для программы, в консоль выводится строка переданная в dll, при использовании разных компиляторов ничего не происходит.
0
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,287
Завершенные тесты: 3
03.08.2015, 14:28 #11
iiieoi, я, конечно, все понимаю, но пожалуйста, не комбинируйте стили программирования на Си и на С++. То приведение указателей как Си, то типы string и vector... Пишите на чем-то одном. Я лично на Си писал бы, раз WinAPI
0
DrOffset
7310 / 4406 / 998
Регистрация: 30.01.2014
Сообщений: 7,242
03.08.2015, 16:49 #12
Цитата Сообщение от iiieoi Посмотреть сообщение
а передача происходит так:
Угу, все понятно. Так нельзя. Между модулями, которые используют разный C++ ABI можно передавать только простые типы.
Вектора, строки т.п. - исключено. То, что это не работает - закономерно и ожидаемо.
0
iiieoi
Заблокирован
03.08.2015, 17:51  [ТС] #13
Цитата Сообщение от DrOffset Посмотреть сообщение
Угу, все понятно. Так нельзя. Между модулями, которые используют разный C++ ABI можно передавать только простые типы.
Вектора, строки т.п. - исключено. То, что это не работает - закономерно и ожидаемо.
Вообщем все оказалось проще, в dll нельзя использовать поток вывода, как только его убрал, все стало хорошо, кстати и сложные типы очень даже неплохо передаются.
0
DrOffset
7310 / 4406 / 998
Регистрация: 30.01.2014
Сообщений: 7,242
03.08.2015, 18:25 #14
Цитата Сообщение от iiieoi Посмотреть сообщение
Вообщем все оказалось проще, в dll нельзя использовать поток вывода, как только его убрал, все стало хорошо, кстати и сложные типы очень даже неплохо передаются.
Не оказалось. Это видимость работы. Игра с UB.
0
iiieoi
Заблокирован
04.08.2015, 18:59  [ТС] #15
Вообщем лучше всего с компилятором MinGW себя показала привязка потока stdin к файлу через freopen(), а затем использование getchar() + свой парсер.

Хотя мне до сих пор не ясно из-за чего может быть такое различие в скорости работы компиляторов, слишком я пока слабо представляю их работу (все эти lib, include и т.д, которые ставятся вместе с компиляторами).
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.08.2015, 18:59
Привет! Вот еще темы с ответами:

Буффер из std::string c_str() - C++
Здравствуйте! такое дело: Проект на Qt5 и С++11. Есть форма с полем ввода. Введённое содержимое должно обработаться отдельным потоком...

Visual c++ input().c_str() вводит мусор - C++
Я создал стринг переменную, получил через getline cin значения, передал их в другой метод, спри этом сконвертировал в .c_str() но...

реализация функции c_str() в моем классе Str - C++
Ребята, вот есть у меня в классе Str данные: private: Vec&lt;char&gt; data; char* buffer; В конструкторе я пишу: Str() :buffer(new...

c_str() или моя голова провалилась в пропасть - C++
Здравствуйте товарищи, один и тот же код приводит меня к правильному решению в 9 билдере, а вот в 10 мне выдает проблему: Unit1.cpp(94):...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
04.08.2015, 18:59
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru