From 9f9000d17793db4e2e323ff1f03f3462c2aab75f Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 7 Jul 2004 21:48:01 +0000 Subject: [PATCH] re PR libstdc++/16401 (ostringstream in gcc 3.4.x very slow for big data) 2004-07-07 Paolo Carlini PR libstdc++/16401 * include/bits/sstream.tcc (overflow): When reallocating _M_string use an exponential grow policy. * testsuite/27_io/basic_stringbuf/overflow/char/1.cc: New. * testsuite/performance/27_io/stringbuf_overflow.cc: New. From-SVN: r84235 --- libstdc++-v3/ChangeLog | 8 +++ libstdc++-v3/include/bits/sstream.tcc | 22 +++---- .../27_io/basic_stringbuf/overflow/char/1.cc | 57 ++++++++++++++++++ .../performance/27_io/stringbuf_overflow.cc | 60 +++++++++++++++++++ 4 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/char/1.cc create mode 100644 libstdc++-v3/testsuite/performance/27_io/stringbuf_overflow.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c01a8c13da3..5d349d93ea7 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2004-07-07 Paolo Carlini + + PR libstdc++/16401 + * include/bits/sstream.tcc (overflow): When reallocating _M_string + use an exponential grow policy. + * testsuite/27_io/basic_stringbuf/overflow/char/1.cc: New. + * testsuite/performance/27_io/stringbuf_overflow.cc: New. + 2004-07-06 Anssi Hannula PR libstdc++/15928 diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc index df5e619a70d..04cd6ec92a2 100644 --- a/libstdc++-v3/include/bits/sstream.tcc +++ b/libstdc++-v3/include/bits/sstream.tcc @@ -83,23 +83,25 @@ namespace std if (__builtin_expect(__testeof, false)) return traits_type::not_eof(__c); - // NB: Start ostringstream buffers at 512 chars. This is an - // experimental value (pronounced "arbitrary" in some of the - // hipper english-speaking countries), and can be changed to - // suit particular needs. - const __size_type __len = std::max(__size_type(_M_string.capacity() + 1), - __size_type(512)); + const __size_type __capacity = _M_string.capacity(); + const __size_type __max_size = _M_string.max_size(); const bool __testput = this->pptr() < this->epptr(); - if (__builtin_expect(!__testput && __len > _M_string.max_size(), false)) + if (__builtin_expect(!__testput && __capacity == __max_size, false)) return traits_type::eof(); // Try to append __c into output sequence in one of two ways. // Order these tests done in is unspecified by the standard. if (!__testput) { - // In virtue of DR 169 (TC) we are allowed to grow more than - // one char. That's easy to implement thanks to the exponential - // growth policy builtin into basic_string. + // NB: Start ostringstream buffers at 512 chars. This is an + // experimental value (pronounced "arbitrary" in some of the + // hipper english-speaking countries), and can be changed to + // suit particular needs. + // Then, in virtue of DR 169 (TC) we are allowed to grow more + // than one char. + const __size_type __opt_len = std::max(__size_type(2 * __capacity), + __size_type(512)); + const __size_type __len = std::min(__opt_len, __max_size); __string_type __tmp; __tmp.reserve(__len); __tmp.assign(_M_string.data(), this->epptr() - this->pbase()); diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/char/1.cc new file mode 100644 index 00000000000..d1608649b80 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/overflow/char/1.cc @@ -0,0 +1,57 @@ +// 2004-07-07 Paolo Carlini + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.7.1.3 basic_stringbuf overridden virtual functions. + +#include +#include +#include + +using namespace std; + +string +data(unsigned len) +{ + string ret; + for (unsigned i = 0; i < len; ++i) + ret.push_back('a' + rand() % 26); + return ret; +} + +void +test01(unsigned iter) +{ + bool test __attribute__((unused)) = true; + + for (unsigned n = 1; n <= iter; n *= 10) + { + const string str = data(n); + stringbuf sstr; + for (unsigned i = 0; i < n; ++i) + sstr.sputc(str[i]); + VERIFY( str == sstr.str() ); + } +} + +int main() +{ + test01(10000000); + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/27_io/stringbuf_overflow.cc b/libstdc++-v3/testsuite/performance/27_io/stringbuf_overflow.cc new file mode 100644 index 00000000000..21b53625c67 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/27_io/stringbuf_overflow.cc @@ -0,0 +1,60 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include + +// libstdc++/16401 ostringstream in gcc 3.4.x very slow for big data +void test01() +{ + using namespace std; + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + + for(unsigned n = 10000; n <= 10000000; n *= 10) + { + ostringstream oss; + oss << "size = " << n; + + ostringstream str; + start_counters(time, resource); + for(unsigned i = 0; i < n; ++i) + str << 'a'; + stop_counters(time, resource); + + report_performance(__FILE__, oss.str(), time, resource); + clear_counters(time, resource); + } +} + +int main() +{ + test01(); + return 0; +}