运行缓慢的代码

时间:2018-03-07 12:47:04

标签: c++ omnet++

我的项目中有以下功能:

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次。 我可能会在这里做一些不需要的事情。

2 个答案:

答案 0 :(得分:4)

如果您要向相同的目的地发送1000条消息,那么您正在执行999次不必要的名称查找。其中每个都可能需要往返网络上的DNS服务器。那是非常低效的。

第一次需要联系特定目的地时,您应该解析名称​​一次。将其缓存以供下次使用。一个好的解析器会告诉你缓存它的安全性有多长。一个更好的解析器将使用操作系统为您执行解析(和缓存),但即使您有其中一个,您仍然在不必要地调用操作系统。

如果没有MCVE,或者至少对L3AddressResolver精确地做什么有所了解,就无法提供更多详细信息。

但是,如果每次目的地不同,那么你真的没什么可做的。您需要留出时间进行查找。您可以做的最好的事情就是异步执行它,以便同时进行多次查找。

取决于您的应用程序的结构,取决于您的要求,如果您事先知道它们是什么,您可能需要考虑提前查找所有名称。然后你仍然花费相同的时间,但在不同的地方(并且可能异步,而其他功能正在发生);然后这个特定的功能将非常快。只有你可以说这是否有用。

答案 1 :(得分:4)

代码可能略有优化:

  • L3Address类使用方便的方法operator<<,因此不需要使用L3AddressResolver().resolve(realLast)INET API).
  • 应该避免使用cout进行日志记录(OMNeT++ Manual)。应使用EV代替cout
  • 要获取模块向量中模块的索引,可以使用getIndex()类中的cModule方法。

提交的代码可能会被重写为以下代码:

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;
   }
}

要提高模拟速度,您应该考虑:

  1. 在发布模式下构建模拟。
  2. 以Cmdenv模式运行模拟。