Returning multiple values from functions in C++
eli.thegreenplace.net
Returning multiple values from functions in C++
1–10 of 67 posts
Re: Returning multiple values from functions in C++
#2Re: Returning multiple values from functions in C++
#3The getline case (boolean and possible value) really wants a type like Haskell's "Maybe" or Rust's Option: a type that either contains nothing or a value.
Re: Returning multiple values from functions in C++
#4The getline case (boolean and possible value) really wants a type like Haskell's "Maybe" or Rust's Option: a type that either contains nothing or a value.
#include
#include
#include
using namespace std;
using namespace boost;
optional getline_(istream &st) {
std::string line;
if(getline(st, line)) return line;
return none;
}
int main() {
int lines = 0;
while(getline_(cin)) lines++;
cout
vs using namespace std;
int main() {
int lines = 0;
string line;
while(getline(cin, line)) lines++;
cout
Run on an input file of 172,544 lines (the GPL-3 license repeated 256 times), the version using "optional" takes 400ms and performs 1,077,504(!) heap allocations, while the more standard version takes just 280ms and performs just 8 allocations.Of course, "wc -l" (GNU) takes just 9ms, so clearly this isn't a great program either way--but it does serve to show that boost::optional can be a surprising performance sink compared to using a bool return value + out parameter.
(tests on debian jessie amd64, i5-3320M @ 2.6GHz, g++ 4.9 -O3, boost 1.55.0.2)
Re: Returning multiple values from functions in C++
#5The getline case (boolean and possible value) really wants a type like Haskell's "Maybe" or Rust's Option: a type that either contains nothing or a value.
Unfortunately the currently available solution (boost::optional) performs enough worse that the difference can be measured in a simple implementation of "wc -l". Consider the following code: #include #include #include using namespace std; using namespace boost; optional getline_(istream &st) { std::string line; if(getline(st, line)) return line; return none; } int main() { int lines = 0; while(getline_(cin)) lines++;…
The basic getline interface removes heap pressure by reusing the same string over and over, even though semantically the optional approach may look cleaner. Eric Niebler showed a while ago (I can't remember where) that this API lends itself perfectly to ranges, and can provide both a reasonable interface without sacrificing performance. IIRC, the API looked somewhat like this:
for (auto& line : getline_range(cin))
f(line); // do something with line, e.g., parse.
The semantics are: iterate over standard input until EOF or error and let the range keep (and reuse) the string internally while exposing it as const-reference by dereferencing.Re: Returning multiple values from functions in C++
#6Re: Returning multiple values from functions in C++
#7 typedef const double * const __restrict__ IN;
typedef double * const __restrict__ OUT;
typedef const int INT_VALUE;
typedef const double FP_VALUE;
void diffuse_c(
OUT runtime_total_s,
OUT runtime_boundary_s,
OUT thermal_energy_updated,
IN thermal_energy,
INT_VALUE nx,
INT_VALUE ny,
INT_VALUE nz
);Re: Returning multiple values from functions in C++
#8The getline case (boolean and possible value) really wants a type like Haskell's "Maybe" or Rust's Option: a type that either contains nothing or a value.
Unfortunately the currently available solution (boost::optional) performs enough worse that the difference can be measured in a simple implementation of "wc -l". Consider the following code: #include #include #include using namespace std; using namespace boost; optional getline_(istream &st) { std::string line; if(getline(st, line)) return line; return none; } int main() { int lines = 0; while(getline_(cin)) lines++;…
Something like this (untested) should be much closer to the non-optional version:
#include
#include
#include
using namespace std;
using namespace boost;
optional getline_(istream &st, string& line) {
if(getline(st, line)) return line;
return none;
}
int main() {
int lines = 0;
string line;
line.reserve( 1024 ); //1024 should be long enough for any line
while(getline_(cin, line )) lines++;
cout Re: Returning multiple values from functions in C++
#9I know it's mentioned specially in the article but the C programmer in me immediately wants to use structs. They don't need to be complex or long lived or even initialized. And as a bonus there's no heap involved anywhere. Either that or just bail out of c++ and use go.