С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.58/19: Рейтинг темы: голосов - 19, средняя оценка - 4.58
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915

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

12.11.2020, 18:48. Показов 4548. Ответов 64
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте,

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

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

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


C++
1
2
3
4
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)Через перебор:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#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:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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.

Почему так или что я делаю не так ?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.11.2020, 18:48
Ответы с готовыми решениями:

Функция для сравнения двух массивов
Функция нужна для ответа на вопрос задачи &quot;Верно ли, что все элементы 1-ой последовательности входят во 2-ю последовательность.&quot;...

Организация цикла сравнения значений элементов двух массивов
Надо, чтобы программа сравнивала РАЗНЫЕ элементы ОДНОГО МАССИВА. Например, со и т.п. Организовал вот так: for (int m = 0; m &lt;...

Сравнение двух символьных массивов - char C++
Доброго времени суток! Столкнулся с проблемой кода программы. Мне нужно сравнить текст из файла (primer.txt), и сравнить его с текстом,...

64
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
12.11.2020, 21:31
Лучший ответ Сообщение было отмечено Optimus11 как решение

Решение

Цитата Сообщение от Optimus11 Посмотреть сообщение
Собстно это можно сделать минимум тремя способами:
C++
1
2
const int res = memcmp(my_char1, my_char2, std::min(std::size(my_char1), std::size(my_char2)));
stat = (res == 0? std::size(my_char1) < std::size(my_char2): res);
Добавлено через 1 минуту
std::lexicographical_compare

Добавлено через 30 минут
Цитата Сообщение от Optimus11 Посмотреть сообщение
-И почему у strcmp - такая скорость ???
Скорее всего, потому что компилятор соптимизировал твои строки. Проверь на динамической памяти.
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
12.11.2020, 21:53  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
C++
1
2
const int res = memcmp(my_char1, my_char2, std::min(std::size(my_char1), std::size(my_char2)));
stat = (res == 0? std::size(my_char1) < std::size(my_char2): res);
Добавлено через 1 минуту
std::lexicographical_compare

Добавлено через 30 минут

Скорее всего, потому что компилятор соптимизировал твои строки. Проверь на динамической памяти.
Да, на динамической памяти strncmp чуть быстрее, чем strcmp. Простой перебор вообще не эффективный по сравнению с этими функциями.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
12.11.2020, 22:07
Цитата Сообщение от Optimus11 Посмотреть сообщение
Да, на динамической памяти strncmp чуть быстрее, чем strcmp. Простой перебор вообще не эффективный по сравнению с этими функциями.
Попробуй вот так
C++
1
2
3
4
5
6
auto *p1 = my_char1;
auto *p2 = my_char2;
while (*(p1++) == *(p2++))
    ;
    
stat = (my_char1 - p1) ==  (my_char2 - p2);
Добавлено через 8 минут
Вернее, что-то типа того. Чтоб одинаковые строки тоже отрабатывали.
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
12.11.2020, 22:12  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Попробуй вот так
C++
1
2
3
4
5
6
auto *p1 = my_char1;
auto *p2 = my_char2;
while (*(p1++) == *(p2++))
    ;
    
stat = (my_char1 - p1) ==  (my_char2 - p2);
Добавлено через 8 минут
Вернее, что-то типа того. Чтоб одинаковые строки тоже отрабатывали.
Так я одинаковые и сравнивал, я просто создал указатель, выделил под него память размером с статический массив и перекопировал туда данные из статического массива и потом уже сравнил указатель и стат.массив
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
12.11.2020, 22:17
Цитата Сообщение от Optimus11 Посмотреть сообщение
Так я одинаковые и сравнивал, я просто создал указатель, выделил под него память размером с статический массив и перекопировал туда данные из статического массива и потом уже сравнил указатель и стат.массив
C++
1
2
3
4
5
6
auto *p1 = my_char1;
auto *p2 = my_char2;
while (*p1 && *(p1++) == *(p2++))
    ;
    
////stat = *p1 == *p2;
Добавлено через 3 минуты
C++
1
2
3
4
5
6
while (*p1 && *p1 == *p2)
{
    ++p1;
    ++p2;
}
stat = *p1 == *p2;
В общем, идея примерно такая. Что-то плохо соображаю под вечер
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
16.11.2020, 21:45  [ТС]
Подскажите пожалуйста, а есть ли функция наподобие strncmp, но которая сравнивает не символы char, а сами значения в байтах ? Ну типы принимает указатель на void, как memcpy с сравнивала бы именно значения байт ?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
16.11.2020, 21:49
Цитата Сообщение от Optimus11 Посмотреть сообщение
Ну типы принимает указатель на void, как memcpy с сравнивала бы именно значения байт ?
Они вроде обе сравнивают именно значения байт.
Или что-ты имеешь ввиду?
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
16.11.2020, 21:54  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Они вроде обе сравнивают именно значения байт.
Или что-ты имеешь ввиду?
Насколько я понимаю strncmp - на вход принимает только char`ы, а я хотел, как бы вот так:

C++
1
2
3
4
char my_char[] = "Hello";
int my_int = 54;
 
_strncmp_(my_char, &my_int, 4);  //Сравнивает 4 байта my_int с 4 байтами my_char
То есть как бы сравнивает байты любых типов с любым типом.
0
38 / 13 / 3
Регистрация: 30.09.2020
Сообщений: 65
16.11.2020, 21:54
Цитата Сообщение от Optimus11 Посмотреть сообщение
наподобие strncmp
memcmp
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
16.11.2020, 21:59  [ТС]
Цитата Сообщение от Ligren Посмотреть сообщение
memcmp
Оно, спасибо!
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
16.11.2020, 22:00
Цитата Сообщение от Optimus11 Посмотреть сообщение
Насколько я понимаю strncmp - на вход принимает только char`ы, а я хотел, как бы вот так:
Нет.
strcmp отличается от mtmcmp только тем, что первая ждёт ноль в конце каждой последовательности
Не очень понимаю, что ты пытаешься сделать
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
16.11.2020, 22:04  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Нет.
strcmp отличается от mtmcmp только тем, что первая ждёт ноль в конце каждой последовательности
Не очень понимаю, что ты пытаешься сделать
Вот это:
C++
1
2
3
4
5
6
7
8
9
10
    char my_char[] = "Hello";
    int my_int = 54;
 
    memcpy(&my_int, my_char,4);
 
 
 
    int status = strncmp(my_char, &my_int, 4);    //Так нельзя, strncmp принимает только char
 
    int status1 = memcmp(my_char, &my_int, 4);  //так можно memcmp принимает указатель на void
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
16.11.2020, 22:09
Цитата Сообщение от Optimus11 Посмотреть сообщение
Вот это:
Да уж.
И так и так хреново
C++
1
2
3
    int status = strncmp(my_char, (char *)&my_int, sizeof(my_int));    //Так нельзя, strncmp принимает только char
 
    int status1 = memcmp(my_char, &my_int, std::min(sizeof(my_char), sizeof(my_int)));  //так можно memcmp принимает указатель на void
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
16.11.2020, 22:11  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Да уж.
И так и так хреново
C++
1
2
3
    int status = strncmp(my_char, (char *)&my_int, sizeof(my_int));    //Так нельзя, strncmp принимает только char
 
    int status1 = memcmp(my_char, &my_int, std::min(sizeof(my_char), sizeof(my_int)));  //так можно memcmp принимает указатель на void
Спасибо!

А почему и так и так хреново ? Разве ну покрайней мере memcmp - не для этого существуют ?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
16.11.2020, 22:12
Цитата Сообщение от Optimus11 Посмотреть сообщение
А почему и так и так хреново ? Разве ну покрайней мере memcmp - не для этого существуют ?
Надо проверять, чтоб не было выхода за пределы массива
0
38 / 13 / 3
Регистрация: 30.09.2020
Сообщений: 65
16.11.2020, 22:12
https://ee.kpi.ua/~yv/edu/amp/book/c/14/14.htm
1
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
16.11.2020, 22:19
strncpy ограничена нулём в конце строки. Если же используешь memcpy, то надо сравнивать ещё и размеры

Добавлено через 2 минуты
C++
1
2
3
int status1 = memcmp(my_char, &my_int, std::min(sizeof(my_char), sizeof(my_int)))
if  (status1 == 0 && sizeof(my_int) != sizeof(my_char))
    status1 = ......
Добавлено через 2 минуты
Воспользуйся std::lexicographical_compare
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
16.11.2020, 22:48  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Воспользуйся std::lexicographical_compare
По сравнению с этими функциями - эта выглядит какой то неудобно используемой
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
16.11.2020, 22:58
Цитата Сообщение от Optimus11 Посмотреть сообщение
По сравнению с этими функциями - эта выглядит какой то неудобно используемой
В смысле, с чего ты это решил? Что-то я не заметил, чтоб ты показал какой-то удобно-используемый код, при этом ещё и рабочий
C++
1
2
auto *p = (char *)&my_int;
std::lexicographical_compare(my_char, mychar + sizeof(mychar), p, p + sizeof(my_int));
Добавлено через 3 минуты
Подозреваю, что ты просто плохо понимаешь, что хочешь сделать. То, что показано выше, это обычно нафиг никому не нужно
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.11.2020, 22:58
Помогаю со студенческими работами здесь

Перемножение столбиком двух массивов char
Здравствуйте. Задание таково: используя символьный массив char, который отображает два положительных целых числа - создать третий...

Сложение двух динамических массивов char* в одну строку
В массивы вводятся данные, масcивы вида : int n,k; char *a,*b; a=new char; b=new char; Как вывести результирующую...

функция сравнения двух массивов
Привет, кто-нибудь знает функцию, которая бы сравнивала два массива и выдавала уникальный элемент в одном из массивов?

Оптимизация сравнения двух массивов
вот сейчас так у меня выглядит код // текст разлаживается на отдельные слова и помещяется в массив ( $arr='bad'; $arr='fix';...

Сравнения двух массивов по двум значениям
Помогите пожалуйста. Есть два массива. Массив: Array( =&gt; Array ( =&gt; name1 =&gt; 0 ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru