Скорость сравнения двух массивов char

164
29 апреля 2022, 15:40

Вдруг возник такой простой вопрос: нужно просто сравнить два массива чаров.

Собстно это можно сделать минимум тремя способами: -простым сравнением и перебором -через strncmp (сравниваем массивы с указанием длинны) -через strcmp(сравнивает массивы с \0)

И у меня вопрос по скорости выполнения эти трех методов, я че то кое чего не понимаю, вот простейший код для тестирования:

char my_char1[] = {1,5,45,255,56,45,1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45,'\0'};
 
 
char my_char2[] = { 1,5,45,255,56,45,1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45, 1,5,45,255,56,45,'\0'};

Сравниваю сначала равные, потом не равные массивы:

1)Через перебор:

#include <ctime>
 
 
int stat = 0;
 
int clock1 = clock();
 
for (int y = 0; y < 100000000; y++)
{
 
    stat = 0;
    for (int i = 0; i < sizeof(my_char2); i++)
    {
        if (my_char1[i] != my_char2[i])
        {
            stat = 1;
            break;
        }
    }
}
 
int clock2 = clock();
 
cout << stat << endl;
cout << clock2-clock1<< endl;

2)Через strncmp:

int stat = 0;
 
 
int clock1 = clock();
for (int y = 0; y < 100000000; y++)
{
    stat = 0;
    if (strncmp(my_char1, my_char2, sizeof(my_char2)) != 0)
    {
        stat = 1;
    }
 
}
int clock2 = clock();
 
cout << stat << endl;
cout << clock2-clock1<< endl;

3)Через strcmp:

int stat = 0;
 
 
int clock1 = clock();
for (int y = 0; y < 100000000; y++)
{
    stat = 0;
    if (strcmp(my_char1, my_char2) != 0)
    {
        stat = 1;
    }
}
int clock2 = clock();
 
cout << stat << endl;
cout << clock2-clock1<< endl;

И вот результаты по скорости (в release) по сравнению равных массивов:

1)3500 (мс) 2)1580 (мс) 3)0 (мс)

У меня собственно два вопроса: -Почему между перебором и strncmp - такая разница в целых два раза ? -И почему у strcmp - такая скорость ???

А вот результаты по скорости по сравнению не равных массивов, не равны они сразу в 1 элементе: 1)60 (мс) 2)232 (мс) 3)0 (мс)

Ну strcmp остается, а вот перебор в этом случае теперь 4 раза быстрее strncmp.

Почему так или что я делаю не так ?

Answer 1

Ну, если заставить не выбрасывать цикл, например, так:

int stat = 0;
for (int y = 0; y < 100000000; y++)
{
    if (strcmp(my_char1, my_char2) == 0)
    {
        stat += 1;
    }
}

то VC++2019 с полной оптимизацией дает (у меня) такие результаты:

  • сравнение вручную - 4070 мс
  • strncmp - 2080 мс
  • strcmp - 55 мс

Если переписать сравнение вручную через int -

for (const int *a = (const int *)my_char1, *b = (const int *)my_char2;
     (char*)a < my_char1 + sizeof(my_char1); a++, b++)
{
    if (*a != *b)

время уменьшается примерно до 1600 мс.

Думаю, в вызове str[n]cmp активно применяются разнообразнейшие возможности оптимизации :)

Да, для x64 -

  • сравнение вручную - 4090 мс / 1140 мс (через int)
  • strncmp - 920 мс
  • strcmp - 58 мс

Многократно с усреднением не считал, так что цифры примерные.

READ ALSO
Проблема с оптимизацией цикла

Проблема с оптимизацией цикла

Программа работает верно для небольших отрезков, но когда задается отрезок к примеру от 1 до 10000000 начинается долгий процесс перебораНужно...

279
Ошибка при компиляции проекта с boost?

Ошибка при компиляции проекта с boost?

Не собирается программа код ниже:

294
SFML: улавливание кириллицы в TextEntered

SFML: улавливание кириллицы в TextEntered

Если использовать код из официальной документации SFML

213