为什么我的 Threaded Thrift 调用很慢?
Why is my Threaded Thrift calls slow?
我的节俭定义是这样的:
list<i32> getValues()
用 C++ 实现。
Server.cpp有如下一段代码:
.....
std::vector<int32_t> store;
TransferServiceHandler() {
for(int i=0;i<100000000;i++)
store.push_back(i);
}
void getValues(std::vector<int32_t> & _return) {
// Your implementation goes here
_return = store;
}
.....
Client.cpp 有一个简单的循环,它调用 getValues():
for(int k=0;k<10;k++){
clock_gettime(CLOCK_REALTIME, &ds_spec);
int64_t dstarted = ds_spec.tv_sec * 1000 + (ds_spec.tv_nsec / 1.0e6);
std::vector<int32_t> values;
client.getValues(values);
clock_gettime(CLOCK_REALTIME, &de_spec);
int64_t dended = de_spec.tv_sec * 1000 + (de_spec.tv_nsec / 1.0e6);
std::cout << "Values size :" << values.size() << " in " << (dended - dstarted) << " ms\n";
}
连接在循环外初始化和关闭。
通常此调用会返回几十万个条目。
当没有数据时(当列表为空时)我可以看到调用在 1ms-2ms 内发生,当我改变数据时 t运行sfer 中有不可预测的延迟。客户端和服务器都运行在同一台机器上(配备10Gb/s以太网,8核和30GB内存)。
遇到这种情况你一般是怎么调试的?我不认为问题出在网络上,因为它是一台 10 Gig 的机器,而且数据大小几乎没有几 MB。
我 运行 具有各种数据大小的基准测试,您可以看到每次调用的延迟都不稳定。
在我看来你正在失去分辨率:
clock_gettime(CLOCK_REALTIME, &ds_spec);
int64_t dstarted = ds_spec.tv_sec * 1000 + (ds_spec.tv_nsec / 1.0e6);
这违背了使用 clock_gettime()
开头的原因;
Here 是关于如何使用 clock_gettime() 分析代码的 link;希望它能解决您的问题。
我指的是解决方案,因为这可能是导致意外分析结果的一个很好的原因。
将数据转换为二进制而不是矢量后,我的性能有了显着提高。
在 thrift 定义文件中,将列表更改为二进制。
这是相同数据量的新基准:
我不确定我是否完全理解客户端和服务器之间的交互,但是您的 getValue
方法可以通过使用移动语义 (C++11) 得到改进,因此您可以移动 store
向量而不是复制(内存操作非常昂贵)如下:
void getValues(std::vector<int32_t> & _return) {
// Your implementation goes here
_return = std::move(store);
}
请注意,只要 store
的内容(现在已移入 _return)不需要在调用 getValue
.
之后继续存在,这就可以正常工作
我的节俭定义是这样的:
list<i32> getValues()
用 C++ 实现。
Server.cpp有如下一段代码:
.....
std::vector<int32_t> store;
TransferServiceHandler() {
for(int i=0;i<100000000;i++)
store.push_back(i);
}
void getValues(std::vector<int32_t> & _return) {
// Your implementation goes here
_return = store;
}
.....
Client.cpp 有一个简单的循环,它调用 getValues():
for(int k=0;k<10;k++){
clock_gettime(CLOCK_REALTIME, &ds_spec);
int64_t dstarted = ds_spec.tv_sec * 1000 + (ds_spec.tv_nsec / 1.0e6);
std::vector<int32_t> values;
client.getValues(values);
clock_gettime(CLOCK_REALTIME, &de_spec);
int64_t dended = de_spec.tv_sec * 1000 + (de_spec.tv_nsec / 1.0e6);
std::cout << "Values size :" << values.size() << " in " << (dended - dstarted) << " ms\n";
}
连接在循环外初始化和关闭。
通常此调用会返回几十万个条目。
当没有数据时(当列表为空时)我可以看到调用在 1ms-2ms 内发生,当我改变数据时 t运行sfer 中有不可预测的延迟。客户端和服务器都运行在同一台机器上(配备10Gb/s以太网,8核和30GB内存)。
遇到这种情况你一般是怎么调试的?我不认为问题出在网络上,因为它是一台 10 Gig 的机器,而且数据大小几乎没有几 MB。
我 运行 具有各种数据大小的基准测试,您可以看到每次调用的延迟都不稳定。
在我看来你正在失去分辨率:
clock_gettime(CLOCK_REALTIME, &ds_spec);
int64_t dstarted = ds_spec.tv_sec * 1000 + (ds_spec.tv_nsec / 1.0e6);
这违背了使用 clock_gettime()
开头的原因;
Here 是关于如何使用 clock_gettime() 分析代码的 link;希望它能解决您的问题。
我指的是解决方案,因为这可能是导致意外分析结果的一个很好的原因。
将数据转换为二进制而不是矢量后,我的性能有了显着提高。
在 thrift 定义文件中,将列表更改为二进制。
这是相同数据量的新基准:
我不确定我是否完全理解客户端和服务器之间的交互,但是您的 getValue
方法可以通过使用移动语义 (C++11) 得到改进,因此您可以移动 store
向量而不是复制(内存操作非常昂贵)如下:
void getValues(std::vector<int32_t> & _return) {
// Your implementation goes here
_return = std::move(store);
}
请注意,只要 store
的内容(现在已移入 _return)不需要在调用 getValue
.