2010-06-28 113 views
0

我正在为我的应用程序(网络工具)设计类。我这个基类:优化C++代码

class Descriptor 
{ 
    // ... 

    public: 
     virtual void data_read (void); 
     virtual void data_write (void); 
     virtual void data_error (void); 

    protected: 
     int socket_descriptor; 
    // ... 
} 

class TcpClient : 
    public Descriptor 
{ 
    // ... 
} 

许多类都基于描述符。我使用epoll监视套接字的事件。当我想寻找的TcpClient对象上的事件我对象的插座和指针到该对象epoll的,代码:

epoll_event descriptor_events; 

descriptor_events.events = EPOLLIN; 
descriptor_events.data.fd = this->socket_descriptor; 
descriptor_events.data.ptr = this; 

epoll_ctl (epoll_descriptor, EPOLL_CTL_ADD, this->socket_descriptor, &descriptor_events); 

我派遣在单独的线程epoll的事件是这样的:

Descriptor *descriptor (NULL); 

// ... 

return_value = epoll_wait (epoll_descriptor, events, 64, -1); 

while (i < return_value) 
{ 
    descriptor = (Descriptor *) (events [i]).data.ptr; 

    if ((events [i]).events & EPOLLOUT) 
     descriptor->data_write(); 
    if ((events [i]).events & EPOLLIN) 
     descriptor->data_read(); 
    if ((events [i]).events & EPOLLERR) 
     descriptor->data_error(); 

    i++; 
} 

程序将处理epoll线程中的大量数据,所以它意味着虚拟函数将在那里被多次调用。我想知道这个解决方案的运行时间成本。

我还想着其他两种实现方式(但我不知道如果the're更快):

typedef void (*function) (Descriptor *) EventFunction; 

class Descriptor 
{ 
    // ... 

    public: 
     EventFunction data_read; 
     EventFunction data_write; 
     EventFunction data_error; 

    protected: 
     Descriptor (EventFunction data_read, 
        EventFunction data_write, 
        EventFunction data_error); 

     int socket_descriptor; 
    // ... 
} 

或使用CRTP。

也许你有其他的想法来实现它?

回答

2

除非另有证明,否则您的原始设计对我来说看起来很好。

优化的第一条规则是先测量,然后只修复真正存在的热点。你会惊讶你的代码在哪里花费时间。关于虚拟函数和函数指针之间的区别几乎肯定是不成熟的优化。在这两种情况下,编译器都会生成代码以跳转到函数指针,但使用虚函数编译器必须先查找vtable。编写惯用的C++代码来做你想做的事情,然后如果你有性能问题的话就进行配置。

(我对你的Descriptor类中的一个注释:除非你打算在具有通用DATA_READ(),data_write(),和data_error(),我建议让他们纯虚方法的方法)

+0

CRTP呢?这有点难看,但不应该提供任何运行时间的开销。 – Goofy 2010-06-28 18:15:34

+1

如果CRTP是一个选项,随时去找它。但对于低级套接字I/O,CPU通常不是瓶颈。很可能它绝对没有区别,因为你不会每秒发送/接收很多数据包。 – jalf 2010-06-28 19:27:43

+0

+1给jalf。有效的低级套接字I/O通常归结为非常严格和高效地使用线程。对于某些操作系统,编写最具可扩展性的服务器甚至需要内核级编程!在Windows上,我们有I/O完成端口。 – stinky472 2010-06-29 08:14:21

1

老实说,您优化此代码的最佳选择可能是完全用Boost ASIO替代它。如上所述,您基本上正在重新实施严格审查和经过良好测试的ASIO库。除非您完全确定您必须推出自己的I/O库,否则您只需使用现有的解决方案即可为您节省大量的开发优化时间。

+0

嗯,我想重新发明轮子(我是一名计算机科学专业的学生),我想简单地尝试自己写这些东西来提高技能和扩展知识。此外,我打算使用SCTP协议,因此Boost.Asio可能不适合我的要求。 – Goofy 2010-06-28 18:14:43

+2

@Goofy:如果提升。Asio不适合您的SCTP需求,或许延长它并为Boost社区贡献你的改进可能是有用的。这样,你既可以提高自己的技能,又可以让其他人利用你的发现。 – Void 2010-06-28 18:26:27

+0

@Goofy:在那种情况下,重新发明!极好的地区选择。我同意Void的观点,即适应Boost支持SCTP是一个值得考虑的想法。如果您在开始时不是C++的专家,那么您几乎肯定会在您完成之时;-) – Rakis 2010-06-28 18:39:50