SGPath: enable move operations

This is done by simply not user-defining the copy constructor,
copy-assignment operator and destructor. See [1] for more info.

[1] http://accu.org/content/conf2014/Howard_Hinnant_Accu_2014.pdf

For the benchmark below (compiled with the next commit to allow sorting
SGPath instances), on Linux amd64 with g++ 6.3.0, I observe that
enabling SGPath move operations with this commit increases the
performance by 31% or 28% respectively, depending on whether I use this:

  // Typical code that creates a data structure in several steps and
  // benefits from move operations (the std::move() does nothing when
  // running the test with move operations disabled: a copy is made).
  auto p = SGPath::fromUtf8(randomString(0, 30));
  v.emplace_back(std::move(p));

or that:

  v.emplace_back(randomString(0, 30))

for the initialization code. Now the benchmark code:

using std::string;

static std::default_random_engine randomNumbersGenerator;

// Utility function: generate a random string whose length is in the
// [minLen, maxLen] range.
string randomString(string::size_type minLen, string::size_type maxLen)
{
  std::uniform_int_distribution<string::size_type> sLenDist(minLen, maxLen);
  std::uniform_int_distribution<int> byteDist(0, 255);
  auto randomByte = std::bind(byteDist, randomNumbersGenerator);

  string::size_type len = sLenDist(randomNumbersGenerator);
  string str;

  while (str.size() < len) {
    str += std::char_traits<char>::to_char_type(randomByte());
  }

  return str;
}

// The test function, run with nbIterations = 500000, minSize = 0 and
// maxSize = 200 to obtain the figures given above.
void SGPath_perfTest(std::size_t nbIterations,
                     std::size_t minSize, std::size_t maxSize)
{
  std::uniform_int_distribution<std::size_t> sizeDist(minSize, maxSize);
  auto randomSize = std::bind(sizeDist, randomNumbersGenerator);

  std::chrono::time_point<std::chrono::system_clock> start, end;
  start = std::chrono::system_clock::now();

  vector<SGPath> v;

  for (std::size_t i=0; i < nbIterations; i++) {
    v = vector<SGPath>{};          // start anew

    for (std::size_t j=0; j < randomSize(); j++) {
      v.emplace_back(randomString(0, 30));
    }

    std::shuffle(v.begin(), v.end(), randomNumbersGenerator);
    std::sort(v.begin(), v.end());
  }

  end = std::chrono::system_clock::now();
  std::chrono::duration<double> elapsedSecs = end - start;
  std::cout << elapsedSecs.count() << "\n"; // duration in seconds
}
This commit is contained in:
Florent Rougon
2017-11-18 08:01:44 +01:00
parent 55d75f18de
commit 1310092c0c
2 changed files with 0 additions and 46 deletions

View File

@@ -240,44 +240,6 @@ SGPath SGPath::fromUtf8(const std::string& bytes, PermissionChecker p)
return SGPath(bytes, p);
}
SGPath::SGPath(const SGPath& p) :
path(p.path),
_permission_checker(p._permission_checker),
_cached(p._cached),
_rwCached(p._rwCached),
_cacheEnabled(p._cacheEnabled),
_canRead(p._canRead),
_canWrite(p._canWrite),
_exists(p._exists),
_isDir(p._isDir),
_isFile(p._isFile),
_modTime(p._modTime),
_size(p._size)
{
}
SGPath& SGPath::operator=(const SGPath& p)
{
path = p.path;
_permission_checker = p._permission_checker,
_cached = p._cached;
_rwCached = p._rwCached;
_cacheEnabled = p._cacheEnabled;
_canRead = p._canRead;
_canWrite = p._canWrite;
_exists = p._exists;
_isDir = p._isDir;
_isFile = p._isFile;
_modTime = p._modTime;
_size = p._size;
return *this;
}
// destructor
SGPath::~SGPath() {
}
// set path
void SGPath::set( const string& p ) {
path = p;

View File

@@ -65,11 +65,6 @@ public:
/** Default constructor */
explicit SGPath(PermissionChecker validator = NULL);
/** Copy contructor */
SGPath(const SGPath& p);
SGPath& operator=(const SGPath& p);
/**
* Construct a path based on the starting path provided.
* @param p initial path
@@ -87,9 +82,6 @@ public:
const std::string& r,
PermissionChecker validator = NULL );
/** Destructor */
~SGPath();
/**
* Set path to a new value
* @param p new path