Comments 80
Я бы с удовольствием посмотрел сравнение std::ostringstream с snprintf для форматирования строк.
+1
А не отпугивает от потоков, кхм, некоторая многословность?
vs
+ во времена g++ 3.3-4.0 в ostringstream была утечка памяти — с тех пор отношусь к ним с большой подозрительностью
printf("%.2f\n", count * 100.0 / total);
vs
std::cout << std::setprecision(2) << std::fixed << count * 100.0 / total << std::endl
+ во времена g++ 3.3-4.0 в ostringstream была утечка памяти — с тех пор отношусь к ним с большой подозрительностью
+1
В общем-то можно убрать std:: повсюду (добавив директиву ранее). Станет чуть короче.
Но вот со скоростью… мда…
Мы тут как-то свой printf делали (чтоб кидать дампы в обработчиках сигнала — где нежелательно, чтобы вдруг где-то malloc() в недрах вдруг вызвался, потому что будет «ой, всё!»). Структура то элементарна — очень простой ДКА — и уже можно по крайней мере целые числа и строки выводить.
Но вот добрались до флотов — и чтоб не городить огород попробовали самый простой метод, что на поверхности: вместо флота 1.99 — выводить целое 199, нарисовав точку после единицы (ну т.е. умножаем флот на precision, и выводим уже int, только в вывод впихиваем точку). Вот его как раз из любопытства забенчили по сравнению со стандартным printf.
Так вот такой бенч:
(UItoA — это наша собственная очень простая реализация; не стал приводить. Но там в самом деле всё просто :) ).
А результат любопытный:
printf — 54.69c (при этом вывелось 3556.232422)
«целое с точкой» — 1.376с (при этом вывелось 3556.232421)
Разница — в 40 раз!
Т.е. если вдруг нужно выводить не хитрые флоты с огромными экспонентами, а вот такие, обычные, и причём нужно выводить много и быстро — свой «велосипед» рулит!
Но вот со скоростью… мда…
Мы тут как-то свой printf делали (чтоб кидать дампы в обработчиках сигнала — где нежелательно, чтобы вдруг где-то malloc() в недрах вдруг вызвался, потому что будет «ой, всё!»). Структура то элементарна — очень простой ДКА — и уже можно по крайней мере целые числа и строки выводить.
Но вот добрались до флотов — и чтоб не городить огород попробовали самый простой метод, что на поверхности: вместо флота 1.99 — выводить целое 199, нарисовав точку после единицы (ну т.е. умножаем флот на precision, и выводим уже int, только в вывод впихиваем точку). Вот его как раз из любопытства забенчили по сравнению со стандартным printf.
Так вот такой бенч:
#ifdef USE_SPRINTF
void outf ( char* out, float arg )
{
sprintf ( out, "%f", arg );
}
const char * sName = "Using sprintf res=%s\n";
#else
void outf ( char* out, float arg )
{
unsigned int x = arg;
arg -=x;
UItoA ( &out, x);
*out++='.';
x=arg*1000000;
UItoA ( &out, x);
*out++='\0';
}
const char * sName = "Using own UItoA res=%s\n";
#endif
int main(int argc, char *argv[])
{
float b;
b=3556.2323;
char cout[100];
int i;
for (i=0; i<100000000; ++i)
outf(cout,b);
printf (sName,cout);
return 0;
}
(UItoA — это наша собственная очень простая реализация; не стал приводить. Но там в самом деле всё просто :) ).
А результат любопытный:
printf — 54.69c (при этом вывелось 3556.232422)
«целое с точкой» — 1.376с (при этом вывелось 3556.232421)
Разница — в 40 раз!
Т.е. если вдруг нужно выводить не хитрые флоты с огромными экспонентами, а вот такие, обычные, и причём нужно выводить много и быстро — свой «велосипед» рулит!
+2
Реализация-то проприетарная?)
+1
Могу посоветовать библиотеку stringencoders, в которой есть функции для преобразования чисел в строки:
code.google.com/p/stringencoders/wiki/PerformanceNumToA
code.google.com/p/stringencoders/wiki/NumToA
Работает значительно быстрее printf-семейства и лицензия MIT (на функции преобразования чисел в строки).
code.google.com/p/stringencoders/wiki/PerformanceNumToA
code.google.com/p/stringencoders/wiki/NumToA
Работает значительно быстрее printf-семейства и лицензия MIT (на функции преобразования чисел в строки).
0
Почему же?
code.google.com/p/sphinxsearch/source/browse/trunk/src/sphinxutils.cpp#1698
Вот, пожалуйста :).
code.google.com/p/sphinxsearch/source/browse/trunk/src/sphinxutils.cpp#1698
Вот, пожалуйста :).
0
крутяк, а я то думаю, почему практически во всем коде по обработке данных в нашей лабе, юзают scanf для чтения, когда есть cin!
надо будет посмотреть как на кластере уменьшится время обработки данных (36гб .txt) если поменять всё на std::stoi
надо будет посмотреть как на кластере уменьшится время обработки данных (36гб .txt) если поменять всё на std::stoi
+1
Не забудьте только выключить синхронизацию, если читаете из cin, иначе будет медленно. (Если читаете из файла, то отключать не нужно).
+1
То есть при считывании из файла данная директива отключения синхронизации бесполезна и не даёт прироста скорости? Или же вообще вредна становится? Что произойдёт, если я всё же включу её перед считыванием данных из файла?
0
Синхронизация включена по умолчанию только на стандартных потоках: cin, cerr, cout, clog. На обычных файлах синхронизация и так должна быть выключена.
0
Что произойдёт, если я всё же включу её перед считыванием данных из файла?Простите — но с чем именно вы собрались синхронизировать файловый поток? Для синхронизации требуется два объекта. cin синхронизирован с stdin, cout — с stdout, а с чем будет синхронизирован созданный вами объект?
+3
Так а где же бенчмарк способа «читать данные большими кусками и дальше работать в памяти»?
+3
походу, это std::istringstream + время на считывание
-1
Готово! Номер 8, новый чемпион.
+3
А как насчёт аналогичной замены getchar_unlocked() в Си на свою реализацию :)?
0
Что-нибудь вроде такого (я особо не оптимизировал, сорри):
#include <stdio.h>
long read_batched(long *out)
{
char buf[20];
long c, x = 0, neg = 0;
char *res = fgets(buf, sizeof(buf), stdin);
if (res == NULL) return 0;
while ((c = *(res++)) != 0) {
if ('0' <= c && c <= '9') {
x = x*10 + c - '0';
} else if (c == '-') {
neg = 1;
} else {
break;
}
}
*out = neg ? -x : x;
return 1;
}
int main()
{
long x;
long max = -1;
while (read_batched(&x)) {
if (x > max) max = x;
}
printf("%ld\n", max);
return 0;
}
0
Или, лучше, вот такого:
#include <stdio.h>
#include <unistd.h>
int main()
{
long max = -1;
char buf[655360];
long c, x = 0, neg = 0, n, i;
while ((n = read(0, buf, sizeof(buf))) > 0) {
for (i = 0; i < n; i++) {
c = buf[i];
if ('0' <= c && c <= '9') {
x = (x<<1) + (x<<3) + c - '0';
} else if (c == '-') {
neg = 1;
} else { // newline
if (x > max) max = x;
x = 0;
neg = 0;
}
}
}
printf("%ld\n", max);
return 0;
}
0
Ваш код — хороший пример того, что некоторые «классические» ручные оптимизации устарели, и только мешают компиляторам.
В вашем коде строка
компилируется в 3 инструкции lea:
тогда как более наивное
всего в 2 таких же инструкции
Поиграться можно тут: gcc.godbolt.org
(Кстати, clang выдаёт второй вариант кода в обоих случаях)
В вашем коде строка
x = (x<<1) + (x<<3) + c - '0';
компилируется в 3 инструкции lea:
leaq 0(,%rbx,8), %rcx
leaq (%rcx,%rbx,2), %rcx
leaq -48(%rax,%rcx), %rbx
тогда как более наивное
x = x*10 + c - '0';
всего в 2 таких же инструкции
leaq (%rbx,%rbx,4), %rcx
leaq -48(%rax,%rcx,2), %rbx
Поиграться можно тут: gcc.godbolt.org
(Кстати, clang выдаёт второй вариант кода в обоих случаях)
+4
Производительность, как и ожидалось, самая лучшая:
10M -> 0.16 с
100M -> 1.80 с
Только писать парсер чего-то более сложного — замучаться.
10M -> 0.16 с
100M -> 1.80 с
Только писать парсер чего-то более сложного — замучаться.
+2
По-моему главная проблема iostreams не в скорости, а в очень спорном синтаксесе, который можно спутать с битовым сдвигом.
-5
Спутать это может только тот, кто ни разу не работал с потоками. Все же обычно ввод-вывод используется как оператор (то есть результат операции никуда не сохраняется) — а битовый сдвиг используется внутри выражения.
+7
Ну да, спутать конечно, врядли, я скорее про то, что это выглядит странно. Выводить и вводить данные уже определенным в языке оператором побитового сдвига. Притомерно так же, еслиб, например, у строк был переопределен оператор деления, для чего-нибудь.
-3
А вас не смущает, что для строк переопределен оператор "+" — то есть математического суммирования? Думаю, что вы просто привыкли к этому и не задумываетесь. А вот в PHP, например (не к ночи будет помянут), насколько я помню, строки конкатенируются оператором "."…
Почему выбрали '<<' и '>>'? Я в головы авторам STL не заглядывал, но думаю, идеи такие:
Парсер C++ (в отличие от Perl, например), не дает возможности придумать какой-то свой, новый оператор. Применяется то, что есть.
Это с одной стороны. А с другой, сами операторы побитового сдвига применяются довольно редко, в основном только в контексте суровой целочисленной арифметики, которая очень редко соседствует в коде с работой ввода-вывода. Разумеется, я тут говорю о программах серьезных, а не о студенческих лабах. Кроме того, знак '<<' прямо просится, чтобы его прочесть как «пропихнуть влево» и даже человеку, незнакомому с возможностью переопределять операторы в C++, очень легко понять, что означает
Что касается оператора деления для строк — а что, я бы, например, не прочь был посмотреть на
Почему выбрали '<<' и '>>'? Я в головы авторам STL не заглядывал, но думаю, идеи такие:
Парсер C++ (в отличие от Perl, например), не дает возможности придумать какой-то свой, новый оператор. Применяется то, что есть.
Это с одной стороны. А с другой, сами операторы побитового сдвига применяются довольно редко, в основном только в контексте суровой целочисленной арифметики, которая очень редко соседствует в коде с работой ввода-вывода. Разумеется, я тут говорю о программах серьезных, а не о студенческих лабах. Кроме того, знак '<<' прямо просится, чтобы его прочесть как «пропихнуть влево» и даже человеку, незнакомому с возможностью переопределять операторы в C++, очень легко понять, что означает
cout << "Hello!"
.Что касается оператора деления для строк — а что, я бы, например, не прочь был посмотреть на
split
, который выглядит как stringList = "a,b,cc,ddd" / ','
. Почему нет? Мы же делим строку на части, так? Отличная метафора…+10
Так дело решается наследованием и реализацией своего оператора. Если сами не хотите, могу сочинить пример)
0
Так Unix shell же, в нём запись в файл (поток) именно так и выглядит $ cmd >> file. Или это вам тоже кажется неудачным решением? Да и интуитивно это вполне понятно. Ведь оператор сдвига не просто так именно такой "<<" или ">>" воспринимается как перемещение чего-либо влево или вправо соответственно. Как уже говорилось выше, никто не считает, что "+" — неудачный оператор для конкетации строк, потому что он интуитивно понятен. Оператор >> в качестве оператора вывода тоже вполне понятен интуитивно и поэтому, как мне кажется, вполне удачен.
+1
UFO just landed and posted this here
Можно было ещё читать с помощью getchar_unlocked в буфер типа char[12] (если в строке больше символов, это в int32 всё равно не влезет — игнорировать или сообщать об ошибке), а потом atoi сделать. Тогда можно не парсить цифры вручную, а скорость должна быть сравнимая с самым быстрым способом.
+1
Ещё нужно помнить про локали. У сишной и плюсовой частей они рулятся независимо, но об этом часто забывают.
Например, выводим через cout. А читаем через sscanf.
В рантайме плюсовая библиотека при запуске выставит локаль в системную. А сишная часть останется в C.
И банальный код, который запишет в файл float-значение через cout, а потом попытается прочитать его через sscanf окажется зависимым от системной локали! (например, запишется число с разделителем-запятой. А при чтении будет ожидаться точка -> ошибка!)
Например, выводим через cout. А читаем через sscanf.
В рантайме плюсовая библиотека при запуске выставит локаль в системную. А сишная часть останется в C.
И банальный код, который запишет в файл float-значение через cout, а потом попытается прочитать его через sscanf окажется зависимым от системной локали! (например, запишется число с разделителем-запятой. А при чтении будет ожидаться точка -> ошибка!)
+8
Интересно было бы с node.js сравнить, например.
-6
Сравните! Я вот, например, взял и померил для Java (ради интереса). Использовал самый тупой способ — класс
И вот вывод ее:
Две с хвостиком секунды. Вполне достойно, как мне кажется. То есть с getchar не сравнить, но с iostream вполне конкурирует…
Scanner
, который является некоторым аналогом потока ввода из iostream. Получилась вот такая прога:package readnum;
import java.util.Scanner;
public class ReadNum {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int max = 0;
while (sc.hasNextInt()) {
int next = sc.nextInt();
if (next > max) {
max = next;
}
}
System.out.println("Max: " + max);
}
}
И вот вывод ее:
$ time java -cp bin readnum.ReadNum < data
Max: 999999
real 0m2.173s
user 0m0.031s
sys 0m0.015s
Две с хвостиком секунды. Вполне достойно, как мне кажется. То есть с getchar не сравнить, но с iostream вполне конкурирует…
0
Сколько у вас было значений на входе? (в посте — 10 миллионов)
+1
Это потому, что я — дурень и читал целые числа. А они закончились на 1 миллионе (который в файле отображен как 1e+6)
Так что беру свои слова назад. У меня — кошмар по производительности:
Чтобы спасти положение, добавляем буфферизацию:
получаем копеечный прирост:
из чего делаем вывод — тормозит
И получаем отличный результат:
То есть те же 2 секунды, что и для iostream. Из чего делаем простой вывод: Java быстро читает и достойно парсит double. Но
Так что беру свои слова назад. У меня — кошмар по производительности:
package readnum;
import java.util.Scanner;
public class ReadNum {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
double max = 0;
while (sc.hasNextDouble()) {
double next = sc.nextDouble();
if (next > max) {
max = next;
}
}
sc.close();
System.out.println("Max: " + max);
}
}
$ time java -cp bin readnum.ReadNum < data
Max: 1.0E7
real 1m2.414s
user 0m0.015s
sys 0m0.031s
Чтобы спасти положение, добавляем буфферизацию:
package readnum;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
public class ReadNum {
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
double max = 0;
while (sc.hasNextDouble()) {
double next = sc.nextDouble();
if (next > max) {
max = next;
}
}
sc.close();
System.out.println("Max: " + max);
}
}
получаем копеечный прирост:
$ time java -cp bin readnum.ReadNum < data
Max: 1.0E7
real 1m1.802s
user 0m0.015s
sys 0m0.015s
из чего делаем вывод — тормозит
Scanner
. Избавляемся от него:package readnum;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ReadNum {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
double max = 0;
String line;
while ((line = br.readLine()) != null) {
double next = Double.parseDouble(line);
if (next > max) {
max = next;
}
}
br.close();
System.out.println("Max: " + max);
}
}
И получаем отличный результат:
$ time java -cp bin readnum.ReadNum < data
Max: 1.0E7
real 0m2.222s
user 0m0.000s
sys 0m0.047s
То есть те же 2 секунды, что и для iostream. Из чего делаем простой вывод: Java быстро читает и достойно парсит double. Но
Scanner
никуда не годится. Тормозит жутко. Если мне надо будет прочитать гигабайт чисел из потока ввода, воспользуюст вашим кодом с getchar и JNI. Слава богу, в реальности таких задач немного :)0
UFO just landed and posted this here
cin из третьего варианта с 100 миллионами справился за 11.97 секунды, а следующая строчка на Haskell — за 6.87. Вот так вот.
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Maybe
import Data.List
main = B.interact $ B.pack . show . foldl' max 0 . map (fst . fromJust . B.readInt) . B.lines
+1
UFO just landed and posted this here
А мне кажется, что не совсем корректно приводить сравнение на максимальной оптимизации компилятора -O3. Всё же по умолчанию у gcc используется оптимизация -O2 — как более безопасная.
+1
У GCC в -O3 нет ничего «небезопасного». Это какой-то старый миф (возможно, в каких-то старых версиях было по-другому).
Другое дело, что, теоретически, оптимизации из O3 могут приводить в раздуванию кода или падению производительности, хотя я на практике такого не наблюдал.
Я сам всегда использую -O3.
-O3
Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-after-reload, -ftree-loop-vectorize, -ftree-loop-distribute-patterns, -ftree-slp-vectorize, -fvect-cost-model, -ftree-partial-pre and -fipa-cp-clone options.
Другое дело, что, теоретически, оптимизации из O3 могут приводить в раздуванию кода или падению производительности, хотя я на практике такого не наблюдал.
Я сам всегда использую -O3.
0
К сожалению это не миф, так как ошибок неправильной работы программы на -O3 было значительное количество по сравнению с -O2…
Я лишь хотел сказать, что немного не верно сравнивать время и возможности работы ввода и вывода, когда компилятор ради увеличения времени компиляции сокращает и упрощает код, тем самым меняя изначальный контекст самого сравнения.
Я лишь хотел сказать, что немного не верно сравнивать время и возможности работы ввода и вывода, когда компилятор ради увеличения времени компиляции сокращает и упрощает код, тем самым меняя изначальный контекст самого сравнения.
0
Скорее всего, ошибки таки в самой программе, а не в оптимизациях компилятора.
+6
Компилятор — такая же программа, написанная программистами, допускающими ошибки.
Поверьте, не всегда правильно работают даже компиляторы.
как пример
Поверьте, не всегда правильно работают даже компиляторы.
как пример
+1
Скорее всего, там ошибки в оптимизациях программы, а не в оптимизациях компилятора.
0
Очень занимательная статья, спасибо.
Вопрос к измерениям: времена получены на единичном запуске или это среднее по какому-то значению?
Вопрос к измерениям: времена получены на единичном запуске или это среднее по какому-то значению?
0
* по количеству запусков, конечно.
0
Я усреднял по 3-5 запускам. Но поскольку не ставилось задачи измерить точно, а только качественно сравнить, я не заморачивался с процедурой измерения.
0
iostreams — это не часть STL, это часть стандартной библиотеки.
+1
А с чем связана такая низкая производительность с clang?
0
А если попробовать mmap? Мне кажется это должно быть быстрее всего.
0
UFO just landed and posted this here
UFO just landed and posted this here
Забавно, что лично у меня на моем процессоре быстрее всего работает такая программа (файл test.c):
Если посмотреть на времена, то получается вот что:
Если компилировать с помощью gcc 4.9, то ваша программа становится чуточку быстрее, а моя — чуточку медленее:
#include <stdio.h>
#include <unistd.h>
int main()
{
long max = -1;
char buf[655361], *bufp;
long c, x = 0, n;
while ((n = read(0, buf, sizeof(buf) - 1)) > 0) {
buf[n] = 0;
bufp = buf;
while ((c = *(bufp++)) != 0) {
c -= '0';
if (c >= 0 && c <= 9) {
x = x*10 + c;
} else if (c == '\n' - '0') {
if (x > max) max = x;
x = 0;
}
}
}
printf("%ld\n", max);
return 0;
}
Если посмотреть на времена, то получается вот что:
$ clang -o merhalak -O3 merhalak.c
$ time ./merhalak <ololo.txt
warning: this program uses gets(), which is unsafe.
683641836811
real 0m1.166s
user 0m1.123s
sys 0m0.037s
$ clang -o test -O3 test.c
$ time ./test <ololo.txt
683641836811
real 0m0.145s
user 0m0.118s
sys 0m0.025s
Если компилировать с помощью gcc 4.9, то ваша программа становится чуточку быстрее, а моя — чуточку медленее:
$ gcc-4.9 -o merhalak -O3 merhalak.c && time ./merhalak <ololo.txt
warning: this program uses gets(), which is unsafe.
683641836811
real 0m1.140s
user 0m1.104s
sys 0m0.033s
$ gcc-4.9 -o test -O3 test.c && time ./test <ololo.txt
683641836811
real 0m0.166s
user 0m0.140s
sys 0m0.024s
0
UFO just landed and posted this here
Используйте fgets вместо get_s ;).
Про c++ и про c++11 в частности я ничего не знаю :). В любом случае, в clang поддержка C++ не очень хорошая
Про c++ и про c++11 в частности я ничего не знаю :). В любом случае, в clang поддержка C++ не очень хорошая
0
UFO just landed and posted this here
В стандарте безопасные функции (с окончанием _s ) описаны в приложении K как optional.
Так что википедия в данном случае неточна.
Так что википедия в данном случае неточна.
0
В clang поддержка C++ как раз считается одной из самых лучших. А с неподдержкой чего столкнулись вы столкнулись?
-3
Я, к счастью, не пишу на C++, поэтому не сталкивался с тем, что в clang что-то не поддерживается. Но мое утверждение было основано на том, что поскольку clang спонсировался долгое время компанией Apple, то в первую очередь в clang развивалась поддержка C и Objective C, и во вторую очередь C++. Сейчас, возможно, ситуация меняется, но очень долгое время поддержка C++ в clang была не в приоритете.
0
threads.h в стандарте объявлен необязательным.
The headers <complex.h>, <stdatomic.h>, and <threads.h> are conditional features that implementations need not support; see 6.10.8.3.
0
Новые версии gcc и clang на Linux x86 поддерживают <threads.h> (ох уж этот хабрапарсер), хотя, вообще говоря, не обязательны для поддержки согласно стандарту. По очевидным причинам — в некоторых ОС потоков просто нет ) Так что уточните, пожалуйста платформу и ось
0
UFO just landed and posted this here
О, извините за невольное введение в заблуждение. Был невнимательным и подумал что речь идёт о C++. GCC до сих пор не поддерживает threading из c11, да и вообще много чего оттуда не поддерживает. Судя по всему, проблема не с компилятором а с библиотекой.
0
результаты на linux mint 17.2,
clang 3.5.0-4, x84_64.
вариант stoi не скомпилился
а мне было лень исправлять
g++ 4.8.2
clang 3.5.0-4, x84_64.
$ seq 1000000 | time testN
Скрытый текст
scanf
10000000
1.35user 0.06system 0:01.52elapsed 92%CPU (0avgtext+0avgdata 2724maxresident)k
0inputs+0outputs (0major+116minor)pagefaults 0swaps
iostream + nosync
10000000
1.47user 0.04system 0:01.59elapsed 95%CPU (0avgtext+0avgdata 2620maxresident)k
0inputs+0outputs (0major+119minor)pagefaults 0swaps
iostream
10000000
4.27user 0.07system 0:04.40elapsed 98%CPU (0avgtext+0avgdata 2600maxresident)k
0inputs+0outputs (0major+112minor)pagefaults 0swaps
iostream + ss + nosync
10000000
6.73user 0.06system 0:06.86elapsed 99%CPU (0avgtext+0avgdata 2624maxresident)k
0inputs+0outputs (0major+119minor)pagefaults 0swaps
iostream + ss
10000000
11.05user 0.13system 0:11.33elapsed 98%CPU (0avgtext+0avgdata 2572maxresident)k
0inputs+0outputs (0major+112minor)pagefaults 0swaps
iostream + ss2 + nosync
10000000
2.42user 0.03system 0:02.49elapsed 98%CPU (0avgtext+0avgdata 2620maxresident)k
0inputs+0outputs (0major+117minor)pagefaults 0swaps
iostream + ss2
10000000
5.51user 0.08system 0:05.62elapsed 99%CPU (0avgtext+0avgdata 2572maxresident)k
0inputs+0outputs (0major+110minor)pagefaults 0swaps
getchar + nosync
10000000
1.05user 0.09system 0:01.18elapsed 96%CPU (0avgtext+0avgdata 2592maxresident)k
0inputs+0outputs (0major+117minor)pagefaults 0swaps
getchar
10000000
1.09user 0.06system 0:01.23elapsed 93%CPU (0avgtext+0avgdata 2536maxresident)k
0inputs+0outputs (0major+111minor)pagefaults 0swaps
getchar unl + nosync
10000000
0.64user 0.08system 0:00.74elapsed 98%CPU (0avgtext+0avgdata 2588maxresident)k
0inputs+0outputs (0major+114minor)pagefaults 0swaps
getchar unl
10000000
0.70user 0.06system 0:00.87elapsed 87%CPU (0avgtext+0avgdata 2536maxresident)k
0inputs+0outputs (0major+111minor)pagefaults 0swaps
10000000
1.35user 0.06system 0:01.52elapsed 92%CPU (0avgtext+0avgdata 2724maxresident)k
0inputs+0outputs (0major+116minor)pagefaults 0swaps
iostream + nosync
10000000
1.47user 0.04system 0:01.59elapsed 95%CPU (0avgtext+0avgdata 2620maxresident)k
0inputs+0outputs (0major+119minor)pagefaults 0swaps
iostream
10000000
4.27user 0.07system 0:04.40elapsed 98%CPU (0avgtext+0avgdata 2600maxresident)k
0inputs+0outputs (0major+112minor)pagefaults 0swaps
iostream + ss + nosync
10000000
6.73user 0.06system 0:06.86elapsed 99%CPU (0avgtext+0avgdata 2624maxresident)k
0inputs+0outputs (0major+119minor)pagefaults 0swaps
iostream + ss
10000000
11.05user 0.13system 0:11.33elapsed 98%CPU (0avgtext+0avgdata 2572maxresident)k
0inputs+0outputs (0major+112minor)pagefaults 0swaps
iostream + ss2 + nosync
10000000
2.42user 0.03system 0:02.49elapsed 98%CPU (0avgtext+0avgdata 2620maxresident)k
0inputs+0outputs (0major+117minor)pagefaults 0swaps
iostream + ss2
10000000
5.51user 0.08system 0:05.62elapsed 99%CPU (0avgtext+0avgdata 2572maxresident)k
0inputs+0outputs (0major+110minor)pagefaults 0swaps
getchar + nosync
10000000
1.05user 0.09system 0:01.18elapsed 96%CPU (0avgtext+0avgdata 2592maxresident)k
0inputs+0outputs (0major+117minor)pagefaults 0swaps
getchar
10000000
1.09user 0.06system 0:01.23elapsed 93%CPU (0avgtext+0avgdata 2536maxresident)k
0inputs+0outputs (0major+111minor)pagefaults 0swaps
getchar unl + nosync
10000000
0.64user 0.08system 0:00.74elapsed 98%CPU (0avgtext+0avgdata 2588maxresident)k
0inputs+0outputs (0major+114minor)pagefaults 0swaps
getchar unl
10000000
0.70user 0.06system 0:00.87elapsed 87%CPU (0avgtext+0avgdata 2536maxresident)k
0inputs+0outputs (0major+111minor)pagefaults 0swaps
вариант stoi не скомпилился
iostreams_performance.cpp:146:22: error: no member named 'stoi' in namespace 'std'
int x = std::stoi(line);
а мне было лень исправлять
g++ 4.8.2
Скрытый текст
scanf
10000000
1.35user 0.06system 0:01.48elapsed 95%CPU (0avgtext+0avgdata 2664maxresident)k
168inputs+0outputs (1major+112minor)pagefaults 0swaps
iostream + nosync
10000000
1.47user 0.05system 0:01.58elapsed 96%CPU (0avgtext+0avgdata 2636maxresident)k
0inputs+0outputs (0major+122minor)pagefaults 0swaps
iostream
10000000
4.30user 0.07system 0:04.41elapsed 99%CPU (0avgtext+0avgdata 2540maxresident)k
0inputs+0outputs (0major+113minor)pagefaults 0swaps
iostream + ss + nosync
10000000
6.89user 0.07system 0:07.03elapsed 98%CPU (0avgtext+0avgdata 2564maxresident)k
0inputs+0outputs (0major+119minor)pagefaults 0swaps
iostream + ss
10000000
10.72user 0.09system 0:10.89elapsed 99%CPU (0avgtext+0avgdata 2544maxresident)k
0inputs+0outputs (0major+113minor)pagefaults 0swaps
iostream + ss2 + nosync
10000000
2.21user 0.04system 0:02.30elapsed 97%CPU (0avgtext+0avgdata 2636maxresident)k
0inputs+0outputs (0major+120minor)pagefaults 0swaps
iostream + ss2
10000000
5.37user 0.08system 0:05.50elapsed 99%CPU (0avgtext+0avgdata 2616maxresident)k
0inputs+0outputs (0major+115minor)pagefaults 0swaps
getchar + nosync
10000000
1.00user 0.06system 0:01.18elapsed 90%CPU (0avgtext+0avgdata 2640maxresident)k
0inputs+0outputs (0major+122minor)pagefaults 0swaps
getchar
10000000
0.94user 0.10system 0:01.15elapsed 90%CPU (0avgtext+0avgdata 2608maxresident)k
0inputs+0outputs (0major+113minor)pagefaults 0swaps
getchar unl + nosync
10000000
0.58user 0.08system 0:00.78elapsed 85%CPU (0avgtext+0avgdata 2636maxresident)k
0inputs+0outputs (0major+120minor)pagefaults 0swaps
getchar unl
10000000
0.58user 0.03system 0:00.64elapsed 97%CPU (0avgtext+0avgdata 2472maxresident)k
0inputs+0outputs (0major+109minor)pagefaults 0swaps
stoi + nosync
10000000
1.14user 0.02system 0:01.25elapsed 93%CPU (0avgtext+0avgdata 2636maxresident)k
0inputs+0outputs (0major+122minor)pagefaults 0swaps
stoi
10000000
4.09user 0.05system 0:04.25elapsed 97%CPU (0avgtext+0avgdata 2544maxresident)k
0inputs+0outputs (0major+113minor)pagefaults 0swaps
10000000
1.35user 0.06system 0:01.48elapsed 95%CPU (0avgtext+0avgdata 2664maxresident)k
168inputs+0outputs (1major+112minor)pagefaults 0swaps
iostream + nosync
10000000
1.47user 0.05system 0:01.58elapsed 96%CPU (0avgtext+0avgdata 2636maxresident)k
0inputs+0outputs (0major+122minor)pagefaults 0swaps
iostream
10000000
4.30user 0.07system 0:04.41elapsed 99%CPU (0avgtext+0avgdata 2540maxresident)k
0inputs+0outputs (0major+113minor)pagefaults 0swaps
iostream + ss + nosync
10000000
6.89user 0.07system 0:07.03elapsed 98%CPU (0avgtext+0avgdata 2564maxresident)k
0inputs+0outputs (0major+119minor)pagefaults 0swaps
iostream + ss
10000000
10.72user 0.09system 0:10.89elapsed 99%CPU (0avgtext+0avgdata 2544maxresident)k
0inputs+0outputs (0major+113minor)pagefaults 0swaps
iostream + ss2 + nosync
10000000
2.21user 0.04system 0:02.30elapsed 97%CPU (0avgtext+0avgdata 2636maxresident)k
0inputs+0outputs (0major+120minor)pagefaults 0swaps
iostream + ss2
10000000
5.37user 0.08system 0:05.50elapsed 99%CPU (0avgtext+0avgdata 2616maxresident)k
0inputs+0outputs (0major+115minor)pagefaults 0swaps
getchar + nosync
10000000
1.00user 0.06system 0:01.18elapsed 90%CPU (0avgtext+0avgdata 2640maxresident)k
0inputs+0outputs (0major+122minor)pagefaults 0swaps
getchar
10000000
0.94user 0.10system 0:01.15elapsed 90%CPU (0avgtext+0avgdata 2608maxresident)k
0inputs+0outputs (0major+113minor)pagefaults 0swaps
getchar unl + nosync
10000000
0.58user 0.08system 0:00.78elapsed 85%CPU (0avgtext+0avgdata 2636maxresident)k
0inputs+0outputs (0major+120minor)pagefaults 0swaps
getchar unl
10000000
0.58user 0.03system 0:00.64elapsed 97%CPU (0avgtext+0avgdata 2472maxresident)k
0inputs+0outputs (0major+109minor)pagefaults 0swaps
stoi + nosync
10000000
1.14user 0.02system 0:01.25elapsed 93%CPU (0avgtext+0avgdata 2636maxresident)k
0inputs+0outputs (0major+122minor)pagefaults 0swaps
stoi
10000000
4.09user 0.05system 0:04.25elapsed 97%CPU (0avgtext+0avgdata 2544maxresident)k
0inputs+0outputs (0major+113minor)pagefaults 0swaps
0
У меня с помощью getline
+std::stod
получается парсить в 2 раза быстрее, чем с помощью boost::spirit::qi
… Конфигурация: MinGW 8.1 64 bit, C++17, boost 1.76. Файл содержит 2 миллиона триста тысяч строк, размер его — 365 мегабайт.
0
Sign up to leave a comment.
Насколько медленны iostreams?