- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个大的txt文件,其中包含约3000万行,每行由行分隔符\n
分隔。我想将所有行读取到无序列表(例如std::list<std::string>
)。
std::list<std::string> list;
std::ifstream file(path);
while(file.good())
{
std::string tmp;
std::getline(file, tmp);
list.emplace_back(tmp);
}
process_data(list);
std::list
,普通数组等)的算法,并且代码必须是跨平台的?
最佳答案
并行读取文件是否不好?读取所有内容的算法是什么
文件到无序容器的行(例如std :: list,正常
数组...)尽可能快地进行操作,而无需使用任何库,并且
代码必须跨平台?
我想我将尝试回答这一问题,以免垃圾评论。在多种情况下,我基本上使用多线程加速了文本文件的解析。但是,此处的关键字是解析,而不是磁盘I / O(尽管几乎所有读取的文本文件都涉及某种程度的解析)。现在首先要注意的是:
VTune在这里告诉我,我的主要热点正在解析中(很抱歉,此图像是数年前拍摄的,我没有展开调用图以显示obj_load
内部大部分时间的内容,但它是sscanf
)。这个分析会议实际上使我感到非常惊讶。尽管进行剖析已有数十年,直到我的直觉不太准确(不够准确,无法进行剖析,请注意,甚至不是亲近,但我已经将我的直观蜘蛛感觉调整到了剖析会话的程度即使没有明显的算法效率低下,通常也不会令我感到惊讶-尽管由于我不太擅长汇编,我可能仍然不知道它们为什么存在。
但是这次我真的很后退,因此感到震惊,因此这个示例一直是我用来向即使是最怀疑的同事展示的示例,这些同事不想使用探查器来显示为什么分析如此重要。他们中的一些人实际上擅长猜测热点的位置,而有些人尽管从未使用过,但实际上正在创建性能出色的解决方案,但是它们都不擅长猜测什么不是热点,而且它们都无法绘制基于他们的预感的调用图。因此,我一直喜欢使用此示例来尝试转换怀疑论者,并让他们花一天时间尝试VTune(而且我们从英特尔那里获得了大量免费许可证,他们与我们合作极大地浪费了我们的团队,我以为是个悲剧,因为VTune是一款非常昂贵的软件)。
这次我被带回的原因并不是因为我对sscanf
热点感到惊讶。毫无疑问,史诗文本文件的非平凡解析通常会因字符串解析而成为瓶颈。我可能已经猜到了。从未接触过分析器的同事可能已经猜到了。我无法猜测的是它有多大的瓶颈。考虑到我正在加载数百万个多边形和顶点,纹理坐标,法线,创建边缘并查找邻接数据,使用索引FOR压缩,将材料从MTL文件关联到多边形,反向工程对象法线存储在OBJ中的事实,我认为文件并合并它们以形成边缘折痕,等等。我至少还将在网格系统中分配大量的时间(我猜想在网格引擎中所花费的时间为25-33%)。
事实证明,网格系统几乎没有让我感到最惊喜的时间,而我的直觉完全是关于它的。到目前为止,解析是超级瓶颈(不是磁盘I / O,不是网格引擎)。
因此,当我将这种优化应用于多线程分析时,它起到了很大的作用。我什至最初以一个非常适度的多线程实现开始,该实现几乎不执行任何解析,只是扫描字符缓冲区中每个线程的行尾以最终在加载线程中进行解析,而这已经有了相当大的帮助(减少了16秒到大约14 IIRC,我最终将它降低到大约8秒,这是在只有两个内核和超线程的i3上。因此,无论如何,通过在单个线程中从文本文件读取的字符缓冲区的多线程解析,您可能可以使事情变得更快。我不会使用线程来使磁盘I / O更快。
我正在将文件中的字符从二进制文件读取到单个线程中的大char缓冲区中,然后使用并行循环,让线程找出该缓冲区中行的整数范围。
// Stores all the characters read in from the file in big chunks.
// This is shared for read-only access across threads.
vector<char> buffer;
// Local to a thread:
// Stores the starting position of each line.
vector<size_t> line_start;
// Stores the assigned buffer range for the thread:
size_t buffer_start, buffer_end;
std::list<std::string> list;
std::ifstream file(path);
while(file.good())
{
std::string tmp;
std::getline(file, tmp);
list.emplace_back(tmp);
}
process_data(list);
std::list<std::string>
中不是一个好主意。实际上,与多线程相比,解决该问题的优先级更高。我将把它变成仅
std::vector<char> all_lines
存储所有字符串,并且您可以使用
std::vector<size_t> line_start
存储
nth
行的起始行位置,可以像这样检索:
// note that 'line' will be EOL-terminated rather than null-terminated
// if it points to the original buffer.
const char* line = all_lines.data() + line_start[n];
std::list
的直接问题是每个节点的堆分配。最重要的是,我们浪费了内存,每行存储两个额外的指针。
std::string
在这里是有问题的,因为避免堆分配的SBO优化会使小字符串占用过多内存(从而增加高速缓存未命中),或者最终仍然会为每个非小字符串调用堆分配。因此,您最终避免了所有这些问题,只是将所有内容都存储在一个巨大的char缓冲区中,例如
std::vector<char>
中。 I / O流(包括字符串流和
getline
之类的函数)的性能也很糟糕,只是让我感到非常失望,因为我的第一个OBJ加载器使用那些I / O流时,它的速度比第二个版本慢20倍以上我移植了所有这些I / O流运算符和函数,并使用
std::string
来利用C函数和我自己在char缓冲区上操作的手动滚动内容。在性能至关重要的上下文中进行解析时,像
sscanf
和
memchr
这样的C函数以及普通的旧字符缓冲区往往比C ++的实现方法快得多,但是您至少仍可以使用
std::vector<char>
存储巨大的缓冲区,例如,避免访问
malloc/free
并在访问存储在其中的字符缓冲区时进行一些调试构建的健全性检查。
关于c++ - 为什么并行读取大文本文件不好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48719966/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!