changeset 30056:7c494a811cc3

load_ascii: Improve performance on platforms with slow setlocale (bug #60984). * libinterp/octave-value/ov-cx-mat.cc (octave_complex_matrix::load_ascii), libinterp/octave-value/ov-flt-cx-mat.cc (octave_float_complex_matrix::load_ascii), libinterp/octave-value/ov-flt-re-mat.cc (octave_float_matrix::load_ascii), libinterp/octave-value/ov-re-mat.cc (octave_matrix::load_ascii): Set locale to "C" for the duration of reading floating point values from the input stream.
author Markus Mützel <markus.muetzel@gmx.de>
date Fri, 27 Aug 2021 16:50:57 +0200
parents d37b0e5ce0a4
children c72ddd9fb513
files libinterp/octave-value/ov-cx-mat.cc libinterp/octave-value/ov-flt-cx-mat.cc libinterp/octave-value/ov-flt-re-mat.cc libinterp/octave-value/ov-re-mat.cc
diffstat 4 files changed, 41 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-cx-mat.cc	Thu Aug 26 18:58:27 2021 -0700
+++ b/libinterp/octave-value/ov-cx-mat.cc	Fri Aug 27 16:50:57 2021 +0200
@@ -27,6 +27,7 @@
 #  include "config.h"
 #endif
 
+#include <clocale>
 #include <istream>
 #include <ostream>
 #include <vector>
@@ -358,6 +359,15 @@
   if (! extract_keyword (is, keywords, kw, val, true))
     error ("load: failed to extract number of rows and columns");
 
+  // Set "C" locale for the duration of this function to avoid the performance
+  // panelty of frequently switching the locale when reading floating point
+  // values from the stream.
+  char *prev_locale = std::setlocale (LC_ALL, nullptr);
+  std::string old_locale (prev_locale ? prev_locale : "");
+  std::setlocale (LC_ALL, "C");
+  octave::unwind_action act
+    ([&old_locale] () { std::setlocale (LC_ALL, old_locale.c_str ()); });
+
   if (kw == "ndims")
     {
       int mdims = static_cast<int> (val);
--- a/libinterp/octave-value/ov-flt-cx-mat.cc	Thu Aug 26 18:58:27 2021 -0700
+++ b/libinterp/octave-value/ov-flt-cx-mat.cc	Fri Aug 27 16:50:57 2021 +0200
@@ -27,6 +27,7 @@
 #  include "config.h"
 #endif
 
+#include <clocale>
 #include <istream>
 #include <ostream>
 #include <vector>
@@ -294,6 +295,7 @@
 octave_float_complex_matrix::save_ascii (std::ostream& os)
 {
   dim_vector dv = dims ();
+
   if (dv.ndims () > 2)
     {
       FloatComplexNDArray tmp = complex_array_value ();
@@ -332,6 +334,15 @@
   if (! extract_keyword (is, keywords, kw, val, true))
     error ("load: failed to extract number of rows and columns");
 
+  // Set "C" locale for the duration of this function to avoid the performance
+  // panelty of frequently switching the locale when reading floating point
+  // values from the stream.
+  char *prev_locale = std::setlocale (LC_ALL, nullptr);
+  std::string old_locale (prev_locale ? prev_locale : "");
+  std::setlocale (LC_ALL, "C");
+  octave::unwind_action act
+    ([&old_locale] () { std::setlocale (LC_ALL, old_locale.c_str ()); });
+
   if (kw == "ndims")
     {
       int mdims = static_cast<int> (val);
--- a/libinterp/octave-value/ov-flt-re-mat.cc	Thu Aug 26 18:58:27 2021 -0700
+++ b/libinterp/octave-value/ov-flt-re-mat.cc	Fri Aug 27 16:50:57 2021 +0200
@@ -27,6 +27,7 @@
 #  include "config.h"
 #endif
 
+#include <clocale>
 #include <istream>
 #include <limits>
 #include <ostream>
@@ -409,6 +410,15 @@
   if (! extract_keyword (is, keywords, kw, val, true))
     error ("load: failed to extract number of rows and columns");
 
+  // Set "C" locale for the duration of this function to avoid the performance
+  // panelty of frequently switching the locale when reading floating point
+  // values from the stream.
+  char *prev_locale = std::setlocale (LC_ALL, nullptr);
+  std::string old_locale (prev_locale ? prev_locale : "");
+  std::setlocale (LC_ALL, "C");
+  octave::unwind_action act
+    ([&old_locale] () { std::setlocale (LC_ALL, old_locale.c_str ()); });
+
   if (kw == "ndims")
     {
       int mdims = static_cast<int> (val);
--- a/libinterp/octave-value/ov-re-mat.cc	Thu Aug 26 18:58:27 2021 -0700
+++ b/libinterp/octave-value/ov-re-mat.cc	Fri Aug 27 16:50:57 2021 +0200
@@ -27,6 +27,7 @@
 #  include "config.h"
 #endif
 
+#include <clocale>
 #include <istream>
 #include <limits>
 #include <ostream>
@@ -512,6 +513,15 @@
   if (! extract_keyword (is, keywords, kw, val, true))
     error ("load: failed to extract number of rows and columns");
 
+  // Set "C" locale for the duration of this function to avoid the performance
+  // panelty of frequently switching the locale when reading floating point
+  // values from the stream.
+  char *prev_locale = std::setlocale (LC_ALL, nullptr);
+  std::string old_locale (prev_locale ? prev_locale : "");
+  std::setlocale (LC_ALL, "C");
+  octave::unwind_action act
+    ([&old_locale] () { std::setlocale (LC_ALL, old_locale.c_str ()); });
+
   if (kw == "ndims")
     {
       int mdims = static_cast<int> (val);