Я играю с многопоточностью, чтобы попытаться лучше понять, как реализовать это в другом проекте, и собрал небольшой пример. Код сначала генерирует 10000 строк. Существует функция foo
, которая перебирает каждую строку между двумя заданными начальным и конечным индексами, проверяя, присутствует ли символ "a" (просто для некоторого синтетического c load).
При вызове foo
в главном потоке с циклом всех 10000 строк время выполнения составляет ~ 72 мс. При использовании двух отдельных потоков th1
и th2
и передаче указателя функции foo
вместе с индексом начала и конца (фактически каждый поток обрабатывает половину 10000 строк), я ожидал, что время выполнения будет меньше ~ 72 мс, так как я понял, что каждый поток будет выполняться одновременно, производя время выполнения ~ 36 мс.
Однако время выполнения такое же, как у l oop, проходящего через все 10000 строк в основном потоке. , Может ли кто-нибудь объяснить мне, почему это так?
#include <iostream>
#include <vector>
#include <memory>
#include <map>
#include <optional>
#include <string>
#include <algorithm>
#include <chrono>
#include <thread>
#include <iomanip>
#include <cmath>
#include <limits>
#include <ratio>
#include <thread>
std::chrono::high_resolution_clock::time_point startTime;
std::vector<std::string> strings;
bool string_contains(std::string needle, std::string haystack)
{
if (haystack.find(needle) != std::string::npos)
{
return true;
}
return false;
}
std::string random_string(int len)
{
std::string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
std::string newstr;
int pos;
while (newstr.size() != len) {
pos = ((rand() % (str.size() - 1)));
newstr += str.substr(pos, 1);
}
return newstr;
}
const double now()
{
std::chrono::duration<double> t = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - startTime);
return t.count();
}
void build_strings()
{
for (size_t i = 0; i < 10000; i++)
{
strings.push_back(random_string(20));
}
}
void foo(size_t start, size_t end, size_t thread)
{
size_t stringsWithA = 0;
for (size_t i = start; i < end; i++)
{
if (string_contains("a", strings[i]))
{
stringsWithA++;
}
}
std::cout << stringsWithA << "\n";
}
int main()
{
build_strings();
auto time_a = now();
foo(0, strings.size(), 0);
auto time_b = now();
std::cout << std::setprecision(10) << std::fixed << "main " << time_b - time_a << "\n";
time_a = now();
std::thread th1(foo, 0, strings.size() / 2, 1);
std::thread th2(foo, strings.size() / 2, strings.size(), 2);
th1.join();
th2.join();
time_b = now();
std::cout << std::setprecision(10) << std::fixed << "threaded " << time_b - time_a << "\n";
std::cin.get();
}