This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Huge performance bottleneck with cin.read.
- To: libstdc++ at gcc dot gnu dot org
- Subject: Huge performance bottleneck with cin.read.
- From: Theodore Papadopoulo <Theodore dot Papadopoulo at sophia dot inria dot fr>
- Date: Wed, 07 Mar 2001 16:23:08 +0100
I have a huge performance problem with a call to a libstdc++-v3
function. istream::read. This is true only for I/O done with cin
(by the way this is a regression with respect to g++-2.95.2 for two
reasons, see below)
#include <iostream>
#include <fstream>
#include <stdio.h>
int
main(int argc,char *argv[])
{
const unsigned data_size = 1367160;
char data[data_size];
std::ifstream ifs(argv[1]);
std::cerr << "Before ifstream::read: " << time(0) << std::endl;
ifs.read(data,data_size);
std::cerr << "After ifstream::read: " << time(0) << std::endl;
std::cerr << "Before cin.read: " << time(0) << std::endl;
std::cin.read(data,data_size);
std::cerr << "After cin.read: " << time(0) << std::endl;
std::cerr << "Before fread: " << time(0) << std::endl;
fread(data,1,data_size,stdin);
std::cerr << "After fread: " << time(0) << std::endl;
}
On my linux redhat 6.2 x86 (P III) machine, for a file toto, I get:
mururoa->ls -l toto
-rw-r--r-- 1 papadop robotvis 1367160 Mar 7 11:38 toto
mururoa->cat toto toto | ./a.out ~/Robotvis++/Libs/Image/tests/images/scully.float.inr
Before ifstream::read: 983970673
After ifstream::read: 983970673
Before cin.read: 983970673
After cin.read: 983970682
Before fread: 983970682
After fread: 983970682
With g++-2.95.2, I get:
mururoa->/usr/local/bin/g++ -g -pg -ftemplate-depth-30 -fPIC -DPIC Test.C
Test.C: In function `int main(int, char **)':
Test.C:13: implicit declaration of function `int time(...)'
[This is a first regression, the new g++ is more lax ]
mururoa->man time [ Added #include <time.h> and recompiled.]
mururoa->/usr/local/bin/g++ -g -pg -ftemplate-depth-30 -fPIC -DPIC Test.C
mururoa->cat toto toto | ./a.out ~/Robotvis++/Libs/Image/tests/images/scully.float.inr
Before ifstream::read: 983978303
After ifstream::read: 983978303
Before cin.read: 983978303
After cin.read: 983978303
Before fread: 983978303
After fread: 983978303
[Second regression 2.95.2 was cin.read(ing) as that as the other ways
of reading]
The crux of the problem seem to be (in fstream.tcc).
// XXX So that istream::getc() will only need to get 1 char,
// as opposed to BUF_SIZE.
if (__fd == 0)
_M_buf_size = 1;
Consequently, characters are read one by one which is extremely
costly.
Is this absolutely necessary (I cannot find support for this in the
standard, but my reading has been quick)???
If yes, how can we avoid this behaviour for the read function:
One solution would be to temporarily set the buffer with a setbuf call,
but then how to set it back to its original value ?
Another would be to just change the size of the buffer temporarily
since the allocated buffer is of optimal size (ie just _M_size is set
to 1).
other ideas ?
My proposal is to remove the above lines (currently trying it).
Theo.
--------------------------------------------------------------------
Theodore Papadopoulo
Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
--------------------------------------------------------------------
PGP signature