2017-03-01 199 views
0

我有这些市场tick数据的大型pcap文件。平均而言,它们每个都是20GB。这些文件被分成数据包。数据包分为标题和消息。消息分为标题和字段。字段分为字段代码和字段值。将char向量转换为字符串的最有效方式

我正在一次读取文件中的一个字符。我有一个文件读取器类,它读取字符并通过const ref将字符传递给4个回调函数,on_packet_delimiter,on_header_char,on_message_delimiter,on_message_char。消息对象使用类似的函数来构造它的字段。

到目前为止,我注意到与仅仅阅读字符而没有对它们做任何事情相比,效率损失很小。

我的代码的一部分,我正在处理消息标题并提取消息的工具符号,这会使流程变得相当慢。

void message::add_char(const char& c) 
{ 
    if (!message_header_complete) { 
    if (is_first_char) { 
     is_first_char = false; 
     if (is_lower_case(c)) { 
     first_prefix = c; 
     } else { 
     symbol_vector.push_back(c); 
     } 
    } else if (is_field_delimiter(c)) { 
     on_message_header_complete(); 
     on_field_delimiter(c); 
    } else { 
     symbol_vector.push_back(c); 
    } 
    } else { 
    // header complete, collect field information 
    if (is_field_delimiter(c)) { 
     on_field_delimiter(c); 
    } else { 
     fp->add_char(c); 
    } 
    } 
} 

... 

void message::on_message_header_complete() 
{ 
    message_header_complete = true; 
    symbol.assign(symbol_vector.begin(),symbol_vector.end()); 
} 

... 

on_message_header_complete()我喂字符来symbol_vector。一旦头完成,我使用矢量迭代器转换为字符串。这是做这件事最有效的方法吗?

+0

[此'std :: string'构造函数引用](http://en.cppreference.com/w/cpp/string/basic_string/basic_string)应该会有所帮助。 –

+0

如果'symbol'是一个成员变量并且是空的,则它的效率与其获得的一样高。 – StoryTeller

+3

尽管我给出了涉及复制的最有效的答案,但我仍然不明白为什么你首先需要'std :: vector '。从一开始就使用'std :: string'! –

回答

1

除了量子物理学家的回答是:的std :: string应该表现为载体确实颇为相似。即使'保留'功能可用于字符串类,如果你打算使用它来提高效率。

添加字符是一样容易,因为它可以得到:

std::string s; 
char c = 's'; 
s += c; 

你可以直接添加字符以您的会员,和你的罚款。但是如果你想保持你的成员干净,直到整个字符串被收集,你仍然应该使用std :: string对象而不是vector。然后您将字符添加到临时字符串,并在完成后,您可以交换的内容。没有复制,只是指针交换(和一些额外的数据,如容量和大小......)。

+0

感谢球员们,这个方法和.append都极大地提高了速度。平均20736ms vs 35459ms。我会把它放在.append上,因为它简单,比平均10次比较中的.append快20ms。对于比我的测试文件大1000倍的主文件,每一点点数都很重要。 – bkarj

+0

您提到了swap函数,它不会复制,而只是交换指针。我很好奇,假设你有一个函数返回一个字符串,并且你在该函数中有一个本地字符串变量来构造返回字符串。当您返回临时字符串变量时,编译器会将其复制到返回的值还是交换? – bkarj

+1

@bkarj它会交换 - 但只有自C++ 11以来。如果您针对较旧的标准进行编译,则会进行复制。看一看[右值引用](http://thbecker.net/articles/rvalue_references/section_01.html)(非常简短:std :: string为第2页提到的'神秘类型'提供了构造函数/赋值运算符)。请注意,通常情况下,在调用此行为时移动语义只适用于基础数据类型支持它的情况。 – Aconcagua

1

如何:

std::string myStr(myVec.begin(), myVec.end()); 

虽然这个作品,我不明白为什么你需要首先使用向量。从头开始使用std::string,并使用myStr.append()添加字符或字符串。

下面是一个例子:

std::string myStr = "abcd"; 
myStr.append(1,'e'); 
myStr.append(std::string("fghi")); 
//now myStr is "abcdefghi" 
相关问题