为什么在使用库时很难授予效率?


10

任何小型数据库处理都可以通过Python / Perl / ...脚本轻松解决,该脚本使用该语言本身的库和/或实用程序。但是,在性能方面,人们倾向于使用C / C ++ /低级语言。根据需求量身定制代码的可能性似乎就是这些语言吸引BigData的原因-涉及内存管理,并行性,磁盘访问甚至低级优化(通过C / C ++级别的汇编构造)。

当然,这样的好处是没有代价的:编写代码,有时甚至是重新发明轮子,可能是非常昂贵/累赘的。尽管有很多可用的库,但是人们倾向于在需要授予性能时自行编写代码。是什么使性能断言在处理大型数据库时无法使用库?

例如,考虑一个企业,该企业会不断爬网网页并解析收集到的数据。对于每个滑动窗口,对提取的数据运行不同的数据挖掘算法。为什么开发人员会放弃使用可用的库/框架(用于爬网,文本处理和数据挖掘)?使用已经实现的东西不仅可以减轻对整个过程进行编码的负担,还可以节省大量时间。

一次拍摄

  • 是什么使自己编写代码成为性能的保证
  • 为什么在必须确保高性能的情况下依赖框架/库会有风险吗?

1
您能澄清确切的问题吗?您可能想到的一些答案可能也会有所帮助。
阿米尔·阿里·阿克巴里

@AmirAliAkbari SeanOwen发布了一个答案,我注意到我的问题不够具体。我已经在他的帖子中添加了评论。请随时提出有关帖子的任何改进建议,否则,我打算将其删除。
鲁本斯

Answers:


4

一遍又一遍地做着重写游戏(并且还在做),我的直接反应就是适应性

虽然框架和库有大量(可能是可交织的)标准任务例程,但是它们的框架属性通常(总是?)不允许使用快捷方式。实际上,大多数框架都具有某种核心基础结构,在该基础结构周围实现了基本功能的核心层。更具体的功能是利用基本层,并位于核心周围的第二层中。

现在,通过快捷方式,我的意思是不使用内核而直接从第二层例程转到另一个第二层例程。(在我的域中)典型的示例是时间戳:您有某种带有时间戳的数据源。到目前为止,工作仅是从有线读取数据并将其传递给核心,以便您的其他代码可以在上面饱餐一顿。

现在,您的行业有很好的理由更改默认时间戳格式(在我的情况下,它们是从unix时间转换为GPS时间)。除非您的框架是针对特定行业的,否则他们不太可能愿意更改时间的核心表示形式,因此您最终会使用几乎可以完成所需功能的框架。每次访问数据时,都必须先将其转换为行业时格式,并且每次要对其进行修改时,都必须将其转换回核心认为合适的任何格式。没有双重转换,就无法将数据直接从源移交给接收器。

这是您手工制作的框架将发挥作用的地方,这只是一个小小的变化,您将对真实世界进行建模,而所有其他(非特定行业的)框架现在都将在性能上处于劣势。

随着时间的流逝,现实世界与模型之间的差异将会加总。有了一个现成的,现成的框架,你会很快将面临这样的问题:我怎么能代表thisthat还是如何使日常X接受/生产Y

到目前为止,这与C / C ++无关。但是,如果由于某种原因,您不能更改框架,即您必须忍受将数据从一端转换到另一端的双重转换,那么通常会使用一些方法以最大程度地减少额外的开销。就我而言,最好将TAI-> UTC或UTC-> TAI转换器留给原始C(或FPGA)使用。没有优雅的可能,没有深奥的智能数据结构使问题变得微不足道。这只是一个无聊的switch语句,为什么不使用编译器擅长于优化该语言的语言呢?


1
+1这可能是我的错,因为我在帖子中不太清楚,所以其他人以前没有听过。这肯定是我一直在寻找的答案。谢谢。
鲁本斯

7

当性能成为问题时,我认为并不是每个人都喜欢C / C ++。

编写低级代码的优点是使用较少的CPU周期,有时甚至使用较少的内存。但是我要指出的是,高级语言可以调用低级语言来实现这一价值。Python和JVM语言可以做到这一点。

数据科学家在其桌面上使用scikit-learn等数据,已经在调用经过高度优化的本机例程来处理数字。编写新的速度代码毫无意义。

在分布式“大数据”上下文中,您通常会遇到数据移动的瓶颈:网络传输和I / O。本机代码无济于事。有用的不是编写相同的代码来提高运行速度,而是编写更智能的代码。

与C / C ++相比,高级语言将使您可以在给定的开发时间内实现更复杂的分布式算法。从规模上讲,具有更好数据移动性的更智能算法将击败笨拙的本机代码。

通常,与新硬件相比,开发人员的时间和错误所带来的成本负担也更大。一个高级开发人员一年的时间可能需要20万美元的全额费用;一年多的时间也占用了数百台服务器的计算时间。在大多数情况下,过度优化而不是给它扔更多的硬件可能没有任何意义。

我不了解有关“授予”,“禁用”和“断言”的后续措施?


很抱歉对于这个误会。我的意图是提出有关控制应用程序的重要性以及库如何放松该控制的答案。当然,您可以假设有关它们的事情(人们通常不重写pthread),但是如果数据发生更改(负载,吞吐量等),则可能需要访问lib源以授予性能。是的,它不一定是C / C ++,尽管它们通常是为hpc选择的语言。我可以删除我的问题,还是想将其更改为更具体的问题?我接受任何改进建议。
鲁本斯2014年

1
不,这是一个很好的问题,如果您愿意,您可以在对问题的编辑中反映您的评论。
肖恩·欧文

请检查该问题是否现在有意义。为了使其更简单,我添加了一个小箱。如果您想在问题中添加一些注意事项,请随时对其进行编辑。
鲁本斯

4

众所周知,在数字世界中,有很多方法可以完成相同的工作/获得预期的结果。

来自代码的责任/风险由开发人员承担。

这个很小,但是我想是.NET世界中一个非常有用的例子。

因此,许多.NET开发人员在其数据序列化上使用内置的BinaryReader-BinaryWriter来提高性能/对该过程进行控制。

这是FrameWork内置BinaryWriter类的CSharp源代码,其中的重载Write方法之一:

// Writes a boolean to this stream. A single byte is written to the stream
// with the value 0 representing false or the value 1 representing true.
// 
public virtual void Write(bool value) 
{
     //_buffer is a byte array which declared in ctor / init codes of the class
    _buffer = ((byte) (value? 1:0));

    //OutStream is the stream instance which BinaryWriter Writes the value(s) into it.
    OutStream.WriteByte(_buffer[0]);
}

如您所见,该方法无需额外分配_buffer变量即可编写:

public virtual void Write(bool value) 
{
    OutStream.WriteByte((byte) (value ? 1 : 0));
}

如果不分配,我们将获得几毫秒的时间。这几毫秒可以接受为“几乎没有”,但是如果有成千上万次写入(即在服务器进程中)怎么办?

让我们假设“ few”为2(毫秒),而数千个实例仅为2.000。这意味着处理时间增加了4秒..4秒后返回。

如果我们继续从.NET进行主题学习,并且您可以从MSDN检查BCL的源代码-.NET基础类库-您会发现开发人员的决定会导致很多性能损失。

来自BCL来源的任何观点正常情况下,您会看到开发人员决定使用while()或foreach()循环,这可以在其代码中实现更快的for()循环。

如此小的收益为我们带来了总体表现

如果我们返回BinaryWriter.Write()方法。

实际上,额外分配给_buffer实现不是开发人员的错误。这完全决定了“保持安全”!

假设我们决定不使用_buffer并决定实现第二种方法。如果我们尝试使用第二种方法通过电线发送数千个字节(即,上载/下载BLOB或CLOB数据),则它通常会失败,因为原因是我们尝试在没有任何检查和控制机制的情况下发送所有数据。当连接丢失时,服务器和客户端都不知道发送的数据是否完成。

如果开发人员决定“保持安全”,那么通常意味着性能成本取决于实施的“保持安全”机制。

但是,如果开发人员决定“冒险,获得性能”,这也不是错。.直到对“风险”编码进行了一些讨论。

还有一个小小的注释:商业库开发人员总是试图保持安全,因为他们不知道代码将在哪里使用。


4

从程序员的角度来看,框架很少将性能作为最高优先级。如果您的图书馆将得到广泛利用,人们可能最看重的是易用性,灵活性和可靠性。

在二级竞争性图书馆中,绩效通常受到重视。“ X库更好,因为它更快。” 即使如此,那些库也会经常折衷选择最理想的解决方案,以换取可以广泛利用的解决方案。

通过使用任何框架,您必然会冒着存在更快解决方案的风险。我可能会说,几乎总是存在一个更快的解决方案。

自己写东西并不能保证性能,但是如果您知道自己在做什么,并且对要求的要求很有限,那么它会有所帮助。

一个示例可能是JSON解析。那里有一百种用于各种语言的库,这些库会将JSON变成可引用的对象,反之亦然。我知道有一种实现可以在CPU寄存器中完成所有操作。它比所有其他解析器都快得多,但是它也非常有限,并且该限制会根据您使用的CPU的不同而有所不同。

构建高性能环境特定的JSON解析器的任务是一个好主意吗?我将利用一个受人尊敬的库(有100个中的99个)。在一个单独的实例中,几个额外的CPU周期乘以一百万次迭代将使开发时间值得。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.