From ef8b25b2c9d4e42bfb75288235abd0c47c704837 Mon Sep 17 00:00:00 2001 From: bkoz Date: Thu, 19 Jun 2003 04:00:59 +0000 Subject: [PATCH] 2003-06-18 Benjamin Kosnik * testsuite/testsuite_performance.h (time_counter): New. (resource_counter): New. (report_performance): New. (start_counters): New. (stop_counters): New. (clear_counters): New. * testsuite/performance/allocator.cc: Instrument. * testsuite/performance/cout_insert_int.cc: Same. * testsuite/performance/complex_norm.cc: Same. * testsuite/performance/filebuf_sputc.cc: New. * testsuite/performance/fstream_seek_write.cc: Same. * testsuite/performance/ifstream_getline.cc: Same. * testsuite/performance/map_create_fill.cc: Same. * testsuite/performance/ofstream_insert_float.cc: Same. * testsuite/performance/ofstream_insert_int.cc: Same. * testsuite/performance/string_append.cc: Convert. * scripts/check_performance: New. * testsuite/Makefile.am (check-performance): New. (CLEANFILES): Add. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@68175 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 22 +++ libstdc++-v3/scripts/check_performance | 48 ++++++ libstdc++-v3/testsuite/Makefile.am | 34 ++-- libstdc++-v3/testsuite/Makefile.in | 38 ++-- libstdc++-v3/testsuite/performance/allocator.cc | 192 ++++++++++++++++++++- libstdc++-v3/testsuite/performance/complex_norm.cc | 34 +++- .../testsuite/performance/cout_insert_int.cc | 14 +- .../testsuite/performance/filebuf_sputc.cc | 73 ++++++++ .../testsuite/performance/fstream_seek_write.cc | 13 +- .../testsuite/performance/ifstream_getline.cc | 15 +- .../testsuite/performance/map_create_fill.cc | 26 +-- .../testsuite/performance/ofstream_insert_float.cc | 16 +- .../testsuite/performance/ofstream_insert_int.cc | 16 +- .../testsuite/performance/string_append.cc | 27 +-- libstdc++-v3/testsuite/testsuite_performance.h | 184 ++++++++++++++++++++ 15 files changed, 672 insertions(+), 80 deletions(-) create mode 100755 libstdc++-v3/scripts/check_performance create mode 100644 libstdc++-v3/testsuite/performance/filebuf_sputc.cc create mode 100644 libstdc++-v3/testsuite/testsuite_performance.h diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ac0426e..2c7df33 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2003-06-18 Benjamin Kosnik + + * testsuite/testsuite_performance.h (time_counter): New. + (resource_counter): New. + (report_performance): New. + (start_counters): New. + (stop_counters): New. + (clear_counters): New. + * testsuite/performance/allocator.cc: Instrument. + * testsuite/performance/cout_insert_int.cc: Same. + * testsuite/performance/complex_norm.cc: Same. + * testsuite/performance/filebuf_sputc.cc: New. + * testsuite/performance/fstream_seek_write.cc: Same. + * testsuite/performance/ifstream_getline.cc: Same. + * testsuite/performance/map_create_fill.cc: Same. + * testsuite/performance/ofstream_insert_float.cc: Same. + * testsuite/performance/ofstream_insert_int.cc: Same. + * testsuite/performance/string_append.cc: Convert. + * scripts/check_performance: New. + * testsuite/Makefile.am (check-performance): New. + (CLEANFILES): Add. + 2003-06-18 Paolo Carlini Benjamin Kosnik diff --git a/libstdc++-v3/scripts/check_performance b/libstdc++-v3/scripts/check_performance new file mode 100755 index 0000000..5fdf581 --- /dev/null +++ b/libstdc++-v3/scripts/check_performance @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +# Script to do performance testing. + +# Invocation +# check_performance SRC_DIR BUILD_DIR + +# 1: variables +# +SRC_DIR=$1 +BUILD_DIR=$2 + +# Now that we've successfully translated the numerical option into +# a symbolic one, we can safely ignore it. +shift + +# This has been true all along. Found out about it the hard way... +case $BASH_VERSION in + 1*) + echo 'You need bash 2.x to run check_performance. Exiting.'; + exit 1 ;; + *) ;; +esac + +flags_script=$BUILD_DIR/scripts/testsuite_flags +INCLUDES=`$flags_script --build-includes` +FLAGS=`$flags_script --cxxflags` +COMPILER=`$flags_script --build-cxx` +SH_FLAG="-Wl,--rpath -Wl,$BUILD_DIR/../../gcc \ + -Wl,--rpath -Wl,$BUILD_DIR/src/.libs" +ST_FLAG="-static" +LINK=$SH_FLAG +CXX="$COMPILER $INCLUDES $FLAGS $LINK" + + +TESTS_FILE="testsuite_files_performance" + +for NAME in `cat $TESTS_FILE` +do + echo $NAME + FILE_NAME="`basename $NAME`" + EXE_NAME="`echo $FILE_NAME | sed 's/cc$/exe/'`" + $CXX $SRC_DIR/testsuite/$NAME -o $EXE_NAME + ./$EXE_NAME + echo "" +done + +exit 0 diff --git a/libstdc++-v3/testsuite/Makefile.am b/libstdc++-v3/testsuite/Makefile.am index e0810e2..218261b 100644 --- a/libstdc++-v3/testsuite/Makefile.am +++ b/libstdc++-v3/testsuite/Makefile.am @@ -125,31 +125,31 @@ check-abi-verbose: endif -# These two special 'check-script' rules use the bash script 'check' -# to do testing. This script is not as portable as the dejagnu test -# harness, and is thus off by default. It does produce interesting -# output however, including various performance analysis items like -# compile time, execution time, and binary size. -check_survey = ${glibcpp_builddir}/scripts/check_survey -check-script: ${check_survey} - -@(chmod + ${check_survey}; \ - ${check_survey} 0) +# These two special 'check-script' rules use the bash script +# 'check_survey' to do testing. This script is not as portable as the +# dejagnu test harness, and is thus off by default. It does produce +# interesting output however, including various performance analysis +# items like compile time, execution time, and binary size. +survey_script = ${glibcpp_builddir}/scripts/check_survey +check-script: ${survey_script} + -@(chmod + ${survey_script}; \ + ${survey_script} 0) -check-script-install: ${check_survey} - -@(chmod + ${check_survey}; \ - ${check_survey} 0) +check-script-install: ${survey_script} + -@(chmod + ${survey_script}; \ + ${survey_script} 0) # Runs the testsuite/performance tests. # Some of these tests create large (~75MB) files, allocate huge # ammounts of memory, or otherwise tie up machine resources. Thus, # running this is off by default. -check_performance=${glibcpp_srcdir}/scripts/check_performance -check-performance: ${check_performance} - -@(chmod + ${check_performance}; \ - ${check_performance} ${glibcpp_srcdir} ${glibcpp_builddir}) +performance_script=${glibcpp_srcdir}/scripts/check_performance +check-performance: ${performance_script} + -@(chmod + ${performance_script}; \ + ${performance_script} ${glibcpp_srcdir} ${glibcpp_builddir}) # By adding these files here, automake will remove them for 'make clean' CLEANFILES = *.txt *.tst *.exe core* filebuf_* tmp* ostream_* *.log *.sum \ - testsuite_* site.exp abi_check baseline_symbols + testsuite_* site.exp abi_check baseline_symbols *.performance diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in index 6802470..ecec0e7 100644 --- a/libstdc++-v3/testsuite/Makefile.in +++ b/libstdc++-v3/testsuite/Makefile.in @@ -181,24 +181,24 @@ abi_check_SOURCES = abi_check.cc baseline_dir = @baseline_dir@ baseline_file = ${baseline_dir}/baseline_symbols.txt -extract_symvers = @glibcpp_srcdir@/scripts/extract_symvers +extract_symvers = @glibcpp_srcdir@/config/abi/extract_symvers -# These two special 'check-script' rules use the bash script 'check' -# to do testing. This script is not as portable as the dejagnu test -# harness, and is thus off by default. It does produce interesting -# output however, including various performance analysis items like -# compile time, execution time, and binary size. -check_survey = ${glibcpp_builddir}/scripts/check_survey +# These two special 'check-script' rules use the bash script +# 'check_survey' to do testing. This script is not as portable as the +# dejagnu test harness, and is thus off by default. It does produce +# interesting output however, including various performance analysis +# items like compile time, execution time, and binary size. +survey_script = ${glibcpp_builddir}/scripts/check_survey # Runs the testsuite/performance tests. # Some of these tests create large (~75MB) files, allocate huge # ammounts of memory, or otherwise tie up machine resources. Thus, # running this is off by default. -check_performance = ${glibcpp_srcdir}/scripts/check_performance +performance_script = ${glibcpp_srcdir}/scripts/check_performance # By adding these files here, automake will remove them for 'make clean' CLEANFILES = *.txt *.tst *.exe core* filebuf_* tmp* ostream_* *.log *.sum \ - testsuite_* site.exp abi_check baseline_symbols + testsuite_* site.exp abi_check baseline_symbols *.performance CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = @@ -527,16 +527,16 @@ new-abi-baseline: @GLIBCPP_TEST_ABI_TRUE@ -@(./abi_check --check-verbose ./current_symbols.txt ${baseline_file}) @GLIBCPP_TEST_ABI_FALSE@check-abi: @GLIBCPP_TEST_ABI_FALSE@check-abi-verbose: -check-script: ${check_survey} - -@(chmod + ${check_survey}; \ - ${check_survey} 0) - -check-script-install: ${check_survey} - -@(chmod + ${check_survey}; \ - ${check_survey} 0) -check-performance: ${check_performance} - -@(chmod + ${check_performance}; \ - ${check_performance} ${glibcpp_srcdir} ${glibcpp_builddir}) +check-script: ${survey_script} + -@(chmod + ${survey_script}; \ + ${survey_script} 0) + +check-script-install: ${survey_script} + -@(chmod + ${survey_script}; \ + ${survey_script} 0) +check-performance: ${performance_script} + -@(chmod + ${performance_script}; \ + ${performance_script} ${glibcpp_srcdir} ${glibcpp_builddir}) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/libstdc++-v3/testsuite/performance/allocator.cc b/libstdc++-v3/testsuite/performance/allocator.cc index a70eda5..42997e9 100644 --- a/libstdc++-v3/testsuite/performance/allocator.cc +++ b/libstdc++-v3/testsuite/performance/allocator.cc @@ -25,15 +25,193 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#include +/* + * + * + * The goal with this application is to compare the performance + * between different STL allocators relative to the default + * __pool_alloc. + * + * The container used for the tests is vector, which as stated by + * SGI "Vector is the simplest of the STL container classes, and in + * many cases the most efficient.". + * + * NOTE! The vector<> container does some "caching" of it's own and + * therefore we redeclare the variable in each iteration (forcing the + * const/destr to be called and thus free memory). + * + * NOTE! The usage of gettimeofday is unwanted since it's not POSIX, + * however I have not found a more generic system call to use - + * ideas are greatly appriciated! + * + * NOTE! This version only does operations on vector. More/other + * data types should maybe also be tested - ideas are always welcome! + * + * I assume that glibc/underlying malloc() implementation has been + * compiled with -O2 thus should this application also be compiled + * with -O2 in order to get relevant results. + */ + +// 2003-02-05 Stefan Olsson + +#include +#include +#include +#include +#include + +using namespace std; +using __gnu_cxx::__malloc_alloc; +using __gnu_cxx::__mt_alloc; + +/* + * In order to avoid that the time it takes for the application to + * startup/shutdown affect the end result, we define a target + * duration (in seconds) for which all tests should run. + * Each test is responsible for "calibrating" their # of iterations + * to come as close as possible to this target based on the time + * it takes to complete the test using the default __pool_alloc. + */ +int target_run_time = 10; + +/* + * The number of iterations to be performed in order to figure out + * the "speed" of this computer and adjust the number of iterations + * needed to come close to target_run_time. + */ +int calibrate_iterations = 100000; + +/* + * The number of values to insert in the vector, 32 will cause + * 5 (re)allocations to be performed (sizes 4, 8, 16, 32 and 64) + * This means that all allocations are within _MAX_BYTES = 128 + * as defined in stl_alloc.h for __pool_alloc. + * Whether or not this value is relevant in "the real world" + * or not I don't know and should probably be investigated in + * more detail. + */ +int insert_values = 32; + +static struct timeval _tstart, _tend; +static struct timezone tz; + +void +tstart(void) +{ + gettimeofday(&_tstart, &tz); +} + +void +tend(void) +{ + gettimeofday(&_tend, &tz); +} + +double +tval() +{ + double t1, t2; + + t1 =(double)_tstart.tv_sec +(double)_tstart.tv_usec/(1000*1000); + t2 =(double)_tend.tv_sec +(double)_tend.tv_usec/(1000*1000); + return t2 - t1; +} + +int +calibrate_test_ints(void) +{ + tstart(); + for (int i = 0; i < calibrate_iterations; i++) + { + vector v1; + + for(int j = 0; j < insert_values; j++) + v1.push_back(1); + } + tend(); + + return(int)((double)target_run_time / tval()) * calibrate_iterations; +} + +double +test_ints_pool_alloc(int iterations) +{ + tstart(); + for(int i = 0; i < iterations; i++) + { + vector v1; + + for(int j = 0; j < insert_values; j++) + v1.push_back(1); + } + tend(); + + return tval(); +} + +double +test_ints_malloc_alloc(int iterations) +{ + tstart(); + for(int i = 0; i < iterations; i++) + { + vector > v1; + + for(int j = 0; j < insert_values; j++) + { + v1.push_back(1); + } + } + tend(); + + return tval(); +} + +double +test_ints_mt_alloc(int iterations) +{ + tstart(); + for(int i = 0; i < iterations; i++) + { + vector > v1; + + for(int j = 0; j < insert_values; j++) + { + v1.push_back(1); + } + } + tend(); + + return tval(); +} -// Primarily a test of the default allocator. // http://gcc.gnu.org/ml/libstdc++/2001-05/msg00105.html -int main () +// http://gcc.gnu.org/ml/libstdc++/2003-05/msg00231.html +int main(void) { - std::list List; - for (int i = 0; i < 10000000; ++i ) - List.push_back( int() ); + using namespace __gnu_cxx_test; + + time_counter time; + resource_counter resource; + + int iterations = calibrate_test_ints(); + + start_counters(time, resource); + test_ints_pool_alloc(iterations); + stop_counters(time, resource); + report_performance(__FILE__, "default", time, resource); + clear_counters(time, resource); + + start_counters(time, resource); + test_ints_malloc_alloc(iterations); + stop_counters(time, resource); + report_performance(__FILE__, "malloc", time, resource); + clear_counters(time, resource); + + start_counters(time, resource); + test_ints_mt_alloc(iterations); + stop_counters(time, resource); + report_performance(__FILE__, "mt", time, resource); + return 0; } - diff --git a/libstdc++-v3/testsuite/performance/complex_norm.cc b/libstdc++-v3/testsuite/performance/complex_norm.cc index 4a42776..952e727 100644 --- a/libstdc++-v3/testsuite/performance/complex_norm.cc +++ b/libstdc++-v3/testsuite/performance/complex_norm.cc @@ -26,34 +26,58 @@ // the GNU General Public License. #include +#include // based on libstdc++/5730, use --fast-math int main() { - typedef std::complex complex_type; + using namespace std; + using namespace __gnu_cxx_test; + + time_counter time; + resource_counter resource; + const int iterations = 2000; + + typedef complex complex_type; complex_type u[2048]; for (int i = 0; i < 2048; ++i) u[i] = 1.0; - for (int i = 0; i < 2000; ++i) + start_counters(time, resource); + for (int i = 0; i < iterations; ++i) { complex_type * p = u; for (int j = 0; j < 2048; ++j) { -#if 1 double u2 = norm(*p); -#else + double t = u2 * 0.1; + *p *= complex_type(cos(t), sin(t)); + ++p; + } + } + stop_counters(time, resource); + report_performance(__FILE__, "norm", time, resource); + clear_counters(time, resource); + + start_counters(time, resource); + for (int i = 0; i < iterations; ++i) + { + complex_type * p = u; + for (int j = 0; j < 2048; ++j) + { // Shouldn't be slower than the above. double ur = real(*p); double ui = imag(*p); double u2 = ur * ur + ui * ui; -#endif double t = u2 * 0.1; *p *= complex_type(cos(t), sin(t)); ++p; } } + stop_counters(time, resource); + report_performance(__FILE__, "", time, resource); + return 0; } diff --git a/libstdc++-v3/testsuite/performance/cout_insert_int.cc b/libstdc++-v3/testsuite/performance/cout_insert_int.cc index 42e44ef..66f15df 100644 --- a/libstdc++-v3/testsuite/performance/cout_insert_int.cc +++ b/libstdc++-v3/testsuite/performance/cout_insert_int.cc @@ -26,11 +26,23 @@ // the GNU General Public License. #include +#include // libstdc++/7076 int main() { - for (int i = 0; i < 150000; i++) + using namespace std; + using namespace __gnu_cxx_test; + + time_counter time; + resource_counter resource; + const int iterations = 150000; + + start_counters(time, resource); + for (int i = 0; i < iterations; i++) std::cout << i << '\n'; + stop_counters(time, resource); + report_performance(__FILE__, "", time, resource); + return 0; } diff --git a/libstdc++-v3/testsuite/performance/filebuf_sputc.cc b/libstdc++-v3/testsuite/performance/filebuf_sputc.cc new file mode 100644 index 0000000..513f75d --- /dev/null +++ b/libstdc++-v3/testsuite/performance/filebuf_sputc.cc @@ -0,0 +1,73 @@ +// Copyright (C) 2003 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 +#include + +// libstdc++/9876 +int main() +{ + using namespace std; + using namespace __gnu_cxx_test; + + time_counter time; + resource_counter resource; + const int iterations = 100000000; + + // C + FILE* file = fopen("tmp", "w+"); + start_counters(time, resource); + for (int i = 0; i < iterations; ++i) + putc(i % 100, file); + stop_counters(time, resource); + fclose(file); + report_performance(__FILE__, "C", time, resource); + clear_counters(time, resource); + + // C unlocked + file = fopen("tmp", "w+"); + start_counters(time, resource); + for (int i = 0; i < iterations; ++i) + putc_unlocked(i % 100, file); + stop_counters(time, resource); + fclose(file); + report_performance(__FILE__, "C unlocked", time, resource); + clear_counters(time, resource); + + + // C++ + filebuf buf; + buf.open("tmp", ios_base::out | ios_base::in | ios_base::trunc); + start_counters(time, resource); + for (int i = 0; i < iterations; ++i) + buf.sputc(i % 100); + stop_counters(time, resource); + report_performance(__FILE__, "C++", time, resource); + + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/fstream_seek_write.cc b/libstdc++-v3/testsuite/performance/fstream_seek_write.cc index 0ea0cfd..d14fd61 100644 --- a/libstdc++-v3/testsuite/performance/fstream_seek_write.cc +++ b/libstdc++-v3/testsuite/performance/fstream_seek_write.cc @@ -26,21 +26,32 @@ // the GNU General Public License. #include +#include // libstdc++/10672 int main() { using namespace std; + using namespace __gnu_cxx_test; + + time_counter time; + resource_counter resource; + const int iterations = 300000; + fstream s("tmp_perf_seek", ios::binary | ios::in | ios::out | ios::trunc); if (s.good()) { - for (int i = 0; i < 300000; i++) + start_counters(time, resource); + for (int i = 0; i < iterations; i++) { s.seekp(0); s.write((char *) & i, sizeof(int)); s.seekp(sizeof(int)); s.write((char *) & i, sizeof(int)); } + stop_counters(time, resource); + report_performance(__FILE__, "", time, resource); } + return 0; } diff --git a/libstdc++-v3/testsuite/performance/ifstream_getline.cc b/libstdc++-v3/testsuite/performance/ifstream_getline.cc index f0a9131..e7b06f3 100644 --- a/libstdc++-v3/testsuite/performance/ifstream_getline.cc +++ b/libstdc++-v3/testsuite/performance/ifstream_getline.cc @@ -26,17 +26,26 @@ // the GNU General Public License. #include +#include // libstdc++/5001 (100,000 line input file) int main () { using namespace std; + using namespace __gnu_cxx_test; + + time_counter time; + resource_counter resource; + const char* name = "/usr/share/dict/linux.words"; ifstream in(name); char buffer[BUFSIZ]; + start_counters(time, resource); while(!in.eof()) - { - in.getline(buffer, BUFSIZ); - } + in.getline(buffer, BUFSIZ); + stop_counters(time, resource); + report_performance(__FILE__, "", time, resource); + + return 0; } diff --git a/libstdc++-v3/testsuite/performance/map_create_fill.cc b/libstdc++-v3/testsuite/performance/map_create_fill.cc index f0fc514..5c3698b 100644 --- a/libstdc++-v3/testsuite/performance/map_create_fill.cc +++ b/libstdc++-v3/testsuite/performance/map_create_fill.cc @@ -20,30 +20,34 @@ #include #include - -static bool test = true; +#include static void create_and_fill(const unsigned int n) { typedef std::map Map; Map m; + bool test = true; for (unsigned int i = 0; i < n; ++i) m[i] = i; - VERIFY ( m.size() == n ); + VERIFY( m.size() == n ); } -void test01() +// http://gcc.gnu.org/ml/libstdc++/2003-03/msg00000.html +int main() { - const unsigned n = 10000000; + using namespace std; + using namespace __gnu_cxx_test; + + time_counter time; + resource_counter resource; + const int iterations = 100000000; - for (unsigned int i = 0; i < n; ++i) + start_counters(time, resource); + for (int i = 0; i < iterations; ++i) create_and_fill( 0 ); -} + stop_counters(time, resource); + report_performance(__FILE__, "", time, resource); -// http://gcc.gnu.org/ml/libstdc++/2003-03/msg00000.html -int main() -{ - test01(); return 0; } diff --git a/libstdc++-v3/testsuite/performance/ofstream_insert_float.cc b/libstdc++-v3/testsuite/performance/ofstream_insert_float.cc index 0fefdd4..549e203 100644 --- a/libstdc++-v3/testsuite/performance/ofstream_insert_float.cc +++ b/libstdc++-v3/testsuite/performance/ofstream_insert_float.cc @@ -26,15 +26,27 @@ // the GNU General Public License. #include +#include // based on libstdc++/8761 poor fstream performance (converted to float) int main() { - std::ofstream out("tmp_perf_float.txt"); - for (int i = 0; i < 10000000; ++i) + using namespace std; + using namespace __gnu_cxx_test; + + time_counter time; + resource_counter resource; + const int iterations = 10000000; + + ofstream out("tmp_perf_float.txt"); + start_counters(time, resource); + for (int i = 0; i < iterations; ++i) { float f = static_cast(i); out << f << "\n"; } + stop_counters(time, resource); + report_performance(__FILE__, "", time, resource); + return 0; }; diff --git a/libstdc++-v3/testsuite/performance/ofstream_insert_int.cc b/libstdc++-v3/testsuite/performance/ofstream_insert_int.cc index 69357f3..f068767 100644 --- a/libstdc++-v3/testsuite/performance/ofstream_insert_int.cc +++ b/libstdc++-v3/testsuite/performance/ofstream_insert_int.cc @@ -26,12 +26,24 @@ // the GNU General Public License. #include +#include // libstdc++/8761 poor fstream performance int main() { - std::ofstream out("tmp_perf_int.txt"); - for (int i = 0; i < 10000000; ++i) + using namespace std; + using namespace __gnu_cxx_test; + + time_counter time; + resource_counter resource; + const int iterations = 10000000; + + ofstream out("tmp_perf_int.txt"); + start_counters(time, resource); + for (int i = 0; i < iterations; ++i) out << i << "\n"; + stop_counters(time, resource); + report_performance(__FILE__, "", time, resource); + return 0; }; diff --git a/libstdc++-v3/testsuite/performance/string_append.cc b/libstdc++-v3/testsuite/performance/string_append.cc index e385eb7..c07c3af 100644 --- a/libstdc++-v3/testsuite/performance/string_append.cc +++ b/libstdc++-v3/testsuite/performance/string_append.cc @@ -28,6 +28,7 @@ #include #include #include +#include using namespace std; @@ -36,7 +37,7 @@ test_append_char(int how_much) { string buf; // no preallocation for (int i = 0; i < how_much; ++i) - buf.append(static_cast(1) , 'x'); + buf.append(static_cast(1) , 'x'); } void @@ -45,29 +46,31 @@ test_append_string(int how_much) string s(static_cast(1) , 'x'); string buf; // no preallocation for (int i = 0; i < how_much; ++i) - buf.append(s); + buf.append(s); } void run_benchmark1(int how_much) { - clock_t t0 = clock(); + using namespace __gnu_cxx_test; + time_counter time; + resource_counter resource; + start_counters(time, resource); test_append_char(how_much); - clock_t t1 = clock(); - cout << "Execution time of " << how_much - << " string::append(char) calls: " - << (static_cast(t1 - t0)/CLOCKS_PER_SEC) << " sec."<< endl; + stop_counters(time, resource); + report_performance(__FILE__, "char", time, resource); } void run_benchmark2(int how_much) { - clock_t t0 = clock(); + using namespace __gnu_cxx_test; + time_counter time; + resource_counter resource; + start_counters(time, resource); test_append_string(how_much); - clock_t t1 = clock(); - cout << "Execution time of " << how_much - << " string::append(const string&) calls: " - << (static_cast(t1 - t0)/CLOCKS_PER_SEC) << " sec." << endl; + stop_counters(time, resource); + report_performance(__FILE__, "string", time, resource); } // libstdc++/5380 diff --git a/libstdc++-v3/testsuite/testsuite_performance.h b/libstdc++-v3/testsuite/testsuite_performance.h new file mode 100644 index 0000000..b9b76cd --- /dev/null +++ b/libstdc++-v3/testsuite/testsuite_performance.h @@ -0,0 +1,184 @@ +// -*- C++ -*- +// Testing performance utilities for the C++ library testsuite. +// +// Copyright (C) 2003 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. + +#ifndef _GLIBCPP_PERFORMANCE_H +#define _GLIBCPP_PERFORMANCE_H + +#include +#include +#include +#include +#include +#include + +namespace __gnu_cxx_test +{ + class time_counter + { + clock_t elapsed_begin; + clock_t elapsed_end; + tms tms_begin; + tms tms_end; + + public: + time_counter() + { this->clear(); } + + void + clear() + { + elapsed_begin = 0; + elapsed_end = 0; + memset(&tms_begin, 0, sizeof(tms)); + memset(&tms_end, 0, sizeof(tms)); + } + + void + start() + { elapsed_begin = times(&tms_begin); } + + void + stop() + { elapsed_end = times(&tms_end); } + + size_t + real_time() const + { return elapsed_end - elapsed_begin; } + + size_t + user_time() const + { return tms_end.tms_utime - tms_begin.tms_utime; } + + size_t + system_time() const + { return tms_end.tms_stime - tms_begin.tms_stime; } + }; + + class resource_counter + { + int who; + rusage rusage_begin; + rusage rusage_end; + struct mallinfo allocation_begin; + struct mallinfo allocation_end; + + public: + resource_counter(int i = RUSAGE_SELF) : who(i) + { this->clear(); } + + void + clear() + { + memset(&rusage_begin, 0, sizeof(rusage_begin)); + memset(&rusage_end, 0, sizeof(rusage_end)); + memset(&allocation_begin, 0, sizeof(allocation_begin)); + memset(&allocation_end, 0, sizeof(allocation_end)); + } + + void + start() + { + if (getrusage(who, &rusage_begin) != 0 ) + memset(&rusage_begin, 0, sizeof(rusage_begin)); + allocation_begin = mallinfo(); + } + + void + stop() + { + if (getrusage(who, &rusage_end) != 0 ) + memset(&rusage_end, 0, sizeof(rusage_end)); + allocation_end = mallinfo(); + } + + int + allocated_memory() const + { return allocation_end.arena - allocation_begin.arena; } + + long + hard_page_fault() const + { return rusage_end.ru_majflt - rusage_begin.ru_majflt; } + + long + swapped() const + { return rusage_end.ru_nswap - rusage_begin.ru_nswap; } + }; + + void + start_counters(time_counter& t, resource_counter& r) + { + t.start(); + r.start(); + } + + void + stop_counters(time_counter& t, resource_counter& r) + { + t.stop(); + r.stop(); + } + + void + clear_counters(time_counter& t, resource_counter& r) + { + t.clear(); + r.clear(); + } + + void + report_performance(const std::string file, const std::string comment, + const time_counter& t, const resource_counter& r) + { + const char space = ' '; + const char tab = '\t'; + const char* name = "libstdc++-v3.performance"; + std::string::const_iterator i = file.begin() + file.find_last_of('/') + 1; + std::string testname(i, file.end()); + + std::ofstream out(name, std::ios_base::app); + + out.setf(std::ios_base::left); + out << std::setw(25) << testname << tab; + out << std::setw(10) << comment << tab; + + out.setf(std::ios_base::right); + out << std::setw(4) << t.real_time() << "r" << space; + out << std::setw(4) << t.user_time() << "u" << space; + out << std::setw(4) << t.system_time() << "s" << space; + // out << std::setw(4) << r.allocated_memory() << "mem" << space; + out << std::setw(4) << r.hard_page_fault() << "pf" << space; + + out << std::endl; + out.close(); + } +}; // namespace __gnu_cxx_test + +#endif // _GLIBCPP_PERFORMANCE_H + -- 2.7.4