OSDN Git Service

2003-06-18 Benjamin Kosnik <bkoz@redhat.com>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Jun 2003 04:00:59 +0000 (04:00 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Jun 2003 04:00:59 +0000 (04:00 +0000)
* 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

15 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/scripts/check_performance [new file with mode: 0755]
libstdc++-v3/testsuite/Makefile.am
libstdc++-v3/testsuite/Makefile.in
libstdc++-v3/testsuite/performance/allocator.cc
libstdc++-v3/testsuite/performance/complex_norm.cc
libstdc++-v3/testsuite/performance/cout_insert_int.cc
libstdc++-v3/testsuite/performance/filebuf_sputc.cc [new file with mode: 0644]
libstdc++-v3/testsuite/performance/fstream_seek_write.cc
libstdc++-v3/testsuite/performance/ifstream_getline.cc
libstdc++-v3/testsuite/performance/map_create_fill.cc
libstdc++-v3/testsuite/performance/ofstream_insert_float.cc
libstdc++-v3/testsuite/performance/ofstream_insert_int.cc
libstdc++-v3/testsuite/performance/string_append.cc
libstdc++-v3/testsuite/testsuite_performance.h [new file with mode: 0644]

index ac0426e..2c7df33 100644 (file)
@@ -1,3 +1,25 @@
+2003-06-18  Benjamin Kosnik  <bkoz@redhat.com>
+
+       * 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  <pcarlini@unitus.it>
             Benjamin Kosnik  <bkoz@redhat.com>
 
diff --git a/libstdc++-v3/scripts/check_performance b/libstdc++-v3/scripts/check_performance
new file mode 100755 (executable)
index 0000000..5fdf581
--- /dev/null
@@ -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
index e0810e2..218261b 100644 (file)
@@ -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
index 6802470..ecec0e7 100644 (file)
@@ -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.
index a70eda5..42997e9 100644 (file)
 // invalidate any other reasons why the executable file might be covered by
 // the GNU General Public License.
 
-#include <list>
+/*
+ * 
+ *
+ * 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<int>. 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 <stefan@snon.net>
+
+#include <vector>
+#include <sys/time.h>
+#include <ext/mt_allocator.h>
+#include <ext/malloc_allocator.h>
+#include <testsuite_performance.h>
+
+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<int> 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<int> 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<int, __malloc_alloc<0> > 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<int, __mt_alloc<0> > 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<int> 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;
 }
-
index 4a42776..952e727 100644 (file)
 // the GNU General Public License.
 
 #include <complex>
+#include <testsuite_performance.h>
 
 // based on libstdc++/5730, use --fast-math
 int main()
 {
-  typedef std::complex<double> complex_type;
+  using namespace std;
+  using namespace __gnu_cxx_test;
+
+  time_counter time;
+  resource_counter resource;
+  const int iterations = 2000;
+
+  typedef complex<double> 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;
 }
 
index 42e44ef..66f15df 100644 (file)
 // the GNU General Public License.
 
 #include <iostream>
+#include <testsuite_performance.h>
 
 // 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 (file)
index 0000000..513f75d
--- /dev/null
@@ -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 <cstdio>
+#include <fstream>
+#include <testsuite_performance.h>
+
+// 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;
+}
index 0ea0cfd..d14fd61 100644 (file)
 // the GNU General Public License.
 
 #include <fstream>
+#include <testsuite_performance.h>
 
 // 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;
 }
index f0a9131..e7b06f3 100644 (file)
 // the GNU General Public License.
 
 #include <fstream>
+#include <testsuite_performance.h>
 
 // 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;
 }
index f0fc514..5c3698b 100644 (file)
 
 #include <map>
 #include <testsuite_hooks.h>
-
-static bool test = true;
+#include <testsuite_performance.h>
 
 static void create_and_fill(const unsigned int n)
 {
   typedef std::map<int, int>  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;
 }
index 0fefdd4..549e203 100644 (file)
 // the GNU General Public License.
 
 #include <fstream>
+#include <testsuite_performance.h>
 
 // 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<float>(i);
       out << f << "\n";
     }
+  stop_counters(time, resource);
+  report_performance(__FILE__, "", time, resource);
+
   return 0;
 };
index 69357f3..f068767 100644 (file)
 // the GNU General Public License.
 
 #include <fstream>
+#include <testsuite_performance.h>
 
 // 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;
 };
index e385eb7..c07c3af 100644 (file)
@@ -28,6 +28,7 @@
 #include <ctime>
 #include <iostream>
 #include <string>
+#include <testsuite_performance.h>
 
 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<string::size_type>(1) , 'x');
+    buf.append(static_cast<string::size_type>(1) , 'x');
 }
 
 void
@@ -45,29 +46,31 @@ test_append_string(int how_much)
   string s(static_cast<string::size_type>(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<float>(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<float>(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 (file)
index 0000000..b9b76cd
--- /dev/null
@@ -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 <sys/times.h>
+#include <sys/resource.h>
+#include <malloc.h>
+#include <string>
+#include <fstream>
+#include <iomanip>
+
+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
+