// ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#include <iostream>
#include <string.h>
#include <chrono>
typedef void TestTrimRight (char * s);
void TrimRight(char* s) {
size_t len = strlen(s);
char* iter = s + len - 1;
if (*iter != ' ') {
// Если последний символ не пробел,
// то и обрезать нечего
return;
}
while (*iter == ' ' /*&& iter != s*/) {
// Идти от конца к началу,
// пока не кончатся пробелы либо строка
iter--;
}
if (iter == s) {
// Если строка пройдена
// и полностью состоит из пробелов
// то результатом будет пустая строка
*iter = '\0';
}
else {
// Если пройдены все пробелы
// и поиск дошел до первого не пробела,
// то заменить первый пробел на конец строки.
*(iter + 1) = '\0';
}
}
void TrimRight2(char* s)
{
char* spc = 0, *p = s;
while (*p)
if (*p == ' ')
for (spc = p; *++p == ' '; );
else
++p;
if (spc && p != s && p[-1] == ' ')* spc = 0;
//return s;
}
void TrimRight3(char* s) {
char* space = nullptr;
char* p = s;
while (*p) {
if (*p == ' ') {
if (space == nullptr) {
space = p;
}
p++;
}
else {
space = nullptr;
p++;
}
}
if (space != nullptr) {
*space = '\0';
}
}
void TrimRight4 (char * s) {
size_t len = strlen (s);
char * it = s + len - 1;
while (it >= s && *it == ' ') {
*(it--) = '\0';
}
}
void TrimRight5(char* s) {
char* space = nullptr;
bool spaceFlag = false;
char* p = s;
while (*p) {
if (*p == ' ') {
space = p;
spaceFlag = true;
} else {
spaceFlag = false;
}
p++;
}
if (spaceFlag) {
*space = '\0';
}
}
const int PROBES = 1000 / 2;
const size_t LENGTH = 1000000;
const int WINDOW = 75;
char * LETTERS;
const int LETTERS_LENGTH = 22;
char * TEST_DATA;
char * SOURCE_DATA;
void createLetters () {
LETTERS = (char *) malloc (sizeof (char) * LETTERS_LENGTH);
for (size_t j = 0; j < LETTERS_LENGTH; j++) {
if (j % 7)
LETTERS[j] = ' ';
else
LETTERS[j] = 'A' + j;
}
}
void createTestData () {
TEST_DATA = (char *) malloc (sizeof (char) * LENGTH);
}
void createSourceData () {
SOURCE_DATA = (char *) malloc (sizeof (char) * LENGTH);
}
char * fillSourceData (size_t len_chars, size_t len_string) {
for (size_t i = 0; i < len_chars; i++) {
SOURCE_DATA[i] = LETTERS[rand () % LETTERS_LENGTH];
}
for (size_t i = len_chars; i < len_string; i++) {
SOURCE_DATA[i] = ' ';
}
SOURCE_DATA[len_string - 1] = '\0';
return SOURCE_DATA;
}
char * fillTestData (int len) {
memcpy (TEST_DATA, SOURCE_DATA, sizeof (char) * len);
return TEST_DATA;
}
double doTest (TestTrimRight * test, char * str) {
auto start = std::chrono::high_resolution_clock::now();
test (str);
auto finish = std::chrono::high_resolution_clock::now();
return (double)(finish - start).count ();
}
double average (double t0, double t1) {
return ((99.0 * t0 + t1) / 100.0);
}
int getWindowedLength (int full_length) {
return
(full_length -
full_length / 100 * (rand () % WINDOW) -
full_length / 100 * (WINDOW >> 2));
}
int main()
{
int i = 0;
int c = 0;
const int c_mod = PROBES / 100 * 10;
int char_length = 0;
int full_length = 0;
double
e0 = 0.0,
e1 = 0.0,
e2 = 0.0,
e3 = 0.0,
e4 = 0.0,
second = 1000000;
createLetters ();
createSourceData ();
createTestData ();
while (i++ < PROBES) {
full_length = LENGTH;
char_length = getWindowedLength (full_length);
fillSourceData (char_length, full_length);
e0 = average (e0, doTest (&TrimRight, fillTestData (full_length)));
e1 = average (e1, doTest (&TrimRight2, fillTestData (full_length)));
e2 = average (e2, doTest (&TrimRight3, fillTestData (full_length)));
e3 = average (e3, doTest (&TrimRight4, fillTestData (full_length)));
e4 = average (e4, doTest (&TrimRight5, fillTestData (full_length)));
c = (c + 1) % c_mod;
if (c == 0) {
printf ("Probe #%-4i: ", i);
printf
("e0 == %5.2f, e1 == %5.2f, e2 == %5.2f, e3 == %5.2f, e4 == %5.2f Ms\n",
e0/second, e1/second, e2/second, e3/second, e4/second);
}
}
std::cout << "Elapsed time TrimRight: " << e0/second << " Ms\n";
std::cout << "Elapsed time TrimRight2: " << e1/second << " Ms\n";
std::cout << "Elapsed time TrimRight3: " << e2/second << " Ms\n";
std::cout << "Elapsed time TrimRight4: " << e3/second << " Ms\n";
std::cout << "Elapsed time TrimRight5: " << e4/second << " Ms\n";
}