慢 运行 代码
Slow running code
我的项目中有以下功能:
void UDPBasicApp::incrementReceiveCounter(L3Address dest) {
char numberOfDestNode[10];
char name[50];
strcpy(name,L3AddressResolver().findHostWithAddress(dest)->getFullPath().c_str());
char temp[20];
char *last = strrchr(name, '.');
char *realLast = last + 1;
std::cout << "Destination is: " << realLast<<", IP is: "<<L3AddressResolver().resolve(realLast);//=====
strcpy(temp,realLast);
strtok(temp,"[");
strcpy(numberOfDestNode, strtok(NULL, "]"));
int realDestNumber = std::stoi(numberOfDestNode);
recArray[realDestNumber]++;
std::cout<<", Number of destination is: "<<realDestNumber<<std::endl;//=================
}
代码运行得很好而且很快,但是当调用这个函数时,执行速度明显变慢。
此代码是 Omnet++ 中模拟项目的一部分,每次节点向另一个节点发送消息时都会调用此函数。所以考虑如果有1000个节点,这个函数会被调用1000次。
我可能在这里做了一些不需要的事情。
如果您向相同 目的地发送 1000 封邮件,那么您将执行 999 次不必要的名称查找。其中每一个都可能需要往返于您网络上的 DNS 服务器。那是非常低效的。
您应该在第一次需要联系特定目的地时解析名称 一次。缓存起来以备下次使用。一个好的解析器会告诉您将其缓存多长时间是安全的。更好的解析器将使用 OS 为您进行解析(和缓存),但即使您有其中之一,您仍然会对 OS.
进行不必要的调用
如果没有 MCVE 或至少对 L3AddressResolver
的确切作用有一些了解,则无法提供更多详细信息。
但是,如果每次的目的地都不一样的话,真的没办法了。您需要留出时间进行查找。您能做的最好的事情就是异步执行它,以便可以同时进行多个查找。
根据您的应用程序的结构和您的要求,如果您事先知道它们是什么,您可能需要考虑提前查找所有名称。然后你仍然花费相同的时间,但在不同的地方(并且可能 异步 而其他功能正在发生);那么 this 特定函数会非常快。只有你能说这是否有帮助。
代码可能略有优化:
L3Address
class有方便的方法operator<<
,所以不用L3AddressResolver().resolve(realLast)
(INET API).
- 应避免使用
cout
进行日志记录 (OMNeT++ Manual)。应使用 EV
而不是 cout
。
- 要获取模块向量中模块的索引,可以使用
cModule
class. 中的 getIndex()
方法
提供的代码可以重写为以下代码:
void UDPBasicApp::incrementReceiveCounter(const L3Address& dest) {
cModule *destHost = L3AddressResolver().findHostWithAddress(dest);
if (destHost) {
int realDestNumber = destHost->getIndex();
recArray[realDestNumber]++;
EV << "Destination is: " << destHost->getName() <<", IP is: "
<< dest << ", Number of destination is: "
<< realDestNumber << std::endl;
}
}
要提高模拟速度,您应该考虑:
- 在发布模式下构建模拟。
- 运行Cmdenv模式下的模拟
我的项目中有以下功能:
void UDPBasicApp::incrementReceiveCounter(L3Address dest) {
char numberOfDestNode[10];
char name[50];
strcpy(name,L3AddressResolver().findHostWithAddress(dest)->getFullPath().c_str());
char temp[20];
char *last = strrchr(name, '.');
char *realLast = last + 1;
std::cout << "Destination is: " << realLast<<", IP is: "<<L3AddressResolver().resolve(realLast);//=====
strcpy(temp,realLast);
strtok(temp,"[");
strcpy(numberOfDestNode, strtok(NULL, "]"));
int realDestNumber = std::stoi(numberOfDestNode);
recArray[realDestNumber]++;
std::cout<<", Number of destination is: "<<realDestNumber<<std::endl;//=================
}
代码运行得很好而且很快,但是当调用这个函数时,执行速度明显变慢。 此代码是 Omnet++ 中模拟项目的一部分,每次节点向另一个节点发送消息时都会调用此函数。所以考虑如果有1000个节点,这个函数会被调用1000次。 我可能在这里做了一些不需要的事情。
如果您向相同 目的地发送 1000 封邮件,那么您将执行 999 次不必要的名称查找。其中每一个都可能需要往返于您网络上的 DNS 服务器。那是非常低效的。
您应该在第一次需要联系特定目的地时解析名称 一次。缓存起来以备下次使用。一个好的解析器会告诉您将其缓存多长时间是安全的。更好的解析器将使用 OS 为您进行解析(和缓存),但即使您有其中之一,您仍然会对 OS.
进行不必要的调用如果没有 MCVE 或至少对 L3AddressResolver
的确切作用有一些了解,则无法提供更多详细信息。
但是,如果每次的目的地都不一样的话,真的没办法了。您需要留出时间进行查找。您能做的最好的事情就是异步执行它,以便可以同时进行多个查找。
根据您的应用程序的结构和您的要求,如果您事先知道它们是什么,您可能需要考虑提前查找所有名称。然后你仍然花费相同的时间,但在不同的地方(并且可能 异步 而其他功能正在发生);那么 this 特定函数会非常快。只有你能说这是否有帮助。
代码可能略有优化:
L3Address
class有方便的方法operator<<
,所以不用L3AddressResolver().resolve(realLast)
(INET API).- 应避免使用
cout
进行日志记录 (OMNeT++ Manual)。应使用EV
而不是cout
。 - 要获取模块向量中模块的索引,可以使用
cModule
class. 中的
getIndex()
方法
提供的代码可以重写为以下代码:
void UDPBasicApp::incrementReceiveCounter(const L3Address& dest) {
cModule *destHost = L3AddressResolver().findHostWithAddress(dest);
if (destHost) {
int realDestNumber = destHost->getIndex();
recArray[realDestNumber]++;
EV << "Destination is: " << destHost->getName() <<", IP is: "
<< dest << ", Number of destination is: "
<< realDestNumber << std::endl;
}
}
要提高模拟速度,您应该考虑:
- 在发布模式下构建模拟。
- 运行Cmdenv模式下的模拟