qicosmos / rest_rpc

modern C++(C++11), simple, easy to use rpc framework
MIT License
1.7k stars 370 forks source link

多线程测试下,性能波动大 #83

Closed Cai-Yao closed 1 year ago

Cai-Yao commented 2 years ago

client

#include <rest_rpc.hpp>
#include <sys/time.h>
#include <vector>
#include <thread>
#include <chrono>
static long long getCurrentPreciseTime() {
    struct timeval tv;  
    gettimeofday(&tv,NULL); 
    return (long long)tv.tv_sec * 1000 * 1000 + tv.tv_usec;
}

using namespace rest_rpc;
using namespace rest_rpc::rpc_service;
void test_add() {
    rpc_client client("127.0.0.1", 9123);
    {
        std::vector<char> req;
        req.resize(128 * 100);
        for (int i = 0; i < 10; i++) {
            bool r = client.connect();
            if (!r) {
                std::cout << "connect timeout" << std::endl;
                return;
            }

            auto result = client.call<std::tuple<int32_t, std::vector<char>, int32_t>>("tuple", i, i, req);
        }

    }
    // client.close();
    client.stop();
}

int main()
{
    std::vector<std::thread> threads;
    long long start_time = getCurrentPreciseTime();
    for(int i = 0; i < 150; i++) {
        threads.push_back(std::thread(test_add));
    }
    for(int i = 0; i < 150; i++) {
        threads[i].join();
    }
    long long end_time = getCurrentPreciseTime();
    printf("read cost %lld\n", end_time - start_time);
    return 0;
}

server

#include "rest_rpc.hpp"
#include <string>
using namespace rest_rpc;
using namespace rpc_service;

struct dummy{
    std::tuple<int32_t, std::vector<char>, int32_t> rpc_test_tuple(rpc_conn conn, int32_t x, int32_t y, std::vector<char> req) {
        std::vector<char> res(8);
        auto tuple = std::make_tuple(x, res, y);

        return tuple;
    }
};

int main() {
    rpc_server server(9123, std::thread::hardware_concurrency() * 3);

    dummy d;
    //server.register_handler("add", &dummy::add, &d);
    server.register_handler("tuple", &dummy::rpc_test_tuple, &d);
    server.run();

    return 0;
}

result

$ ./client 
read cost 48257
$ ./client 
read cost 50969
$ ./client 
read cost 3021651
$ ./client 
read cost 3020548
$ ./client 
read cost 3030853
$ ./client 
read cost 3034473
$ ./client 
read cost 3031834
$ ./client 
read cost 3039597
$ ./client 
read cost 48282
$ ./client 
read cost 51913
$ ./client 
read cost 3038084

请问这是什么原因,是因为哪里的细节没有注意到吗

qicosmos commented 2 years ago

你这测试方法不对呀,你用100多个线程去测试,线程切换的开销会很大,不是已经有一个benchamrk client的例子了吗? https://github.com/qicosmos/rest_rpc/blob/master/examples/client/main.cpp#L616 用client的异步call,启动这样的几个client就够了。

qicosmos commented 2 years ago

同步client call用起来方便,但是效率没有client call效率高,不过平时开发的时候同步call一般情况下性能也够用,性能测试下用异步call可以让client请求的效率很高,性能测试数据才会比较准确。

Cai-Yao commented 2 years ago

嗯好,我使用benchamrk client的例子试试