C++ 风格与性能?

2024-03-25

C++ 风格与性能 - 使用 C 风格的东西,比某些 C++ 等价物更快,这是不好的做法吗?例如:

  • 不要使用atoi(), itoa(), atol(), ETC。 !使用std::stringstream

  • 永远不要使用原始指针,而是使用智能指针 - 好吧,它们真的很有用,每个人都知道,我知道,我一直使用它们,我知道它们比原始指针好多少,但有时它是完全安全的使用原始指针..为什么不呢? “不是C++风格?

  • 不使用按位运算 - C 风格?和?当你确定自己在做什么时为什么不呢?例如 - 不要按位交换变量(a ^= b; b ^= a; a ^= b;) - 使用标准的三步交换。不要使用左移来乘以二。等等,等等(好吧,这不是 C++ 风格与 C 风格的对比,但仍然“不是很好的做法”)

  • 最后,最昂贵的 - “不要使用 enum-s 返回代码,它太 C 风格,对不同的错误使用异常”?为什么?好吧,当我们谈论深层次的错误处理时——好吧,但为什么总是这样呢?例如,当我们谈论一个函数时,它返回不同的错误代码,这有什么问题当错误处理仅在函数中实现时,调用第一个函数?我的意思是 - 不需要在上层传递错误代码。异常是相当慢的,而且它们是例外情况用于特殊情况,而不是......美丽。

  • 等等等等

好吧,我知道好的编码风格是非常非常重要编译器优化非常强大。但我也知道它有多贵异常处理 http://www.codeproject.com/KB/cpp/exceptionhandler.aspx,(一些) smart_pointers 是如何实现的,并且始终不需要 smart_ptr ..我知道,例如,atoi是不是那么“安全”std::stringstream是,但仍然......性能怎么样?


EDIT:我不是在谈论一些非常困难的事情,这些事情只是 C 风格特有的。我的意思是 - 不要想知道使用函数指针或虚拟方法以及这些东西,C++ 程序员可能不知道,如果从未使用过这些东西(而 C 程序员一直这样做)。我正在谈论一些更常见和简单的事情,例如示例中的内容。


一般来说,您忽略的是 C 方式通常并不更快。它看起来更像是黑客攻击,人们经常think黑客攻击速度更快。

永远不要使用原始指针,而是使用智能指针 - 好吧,它们真的很有用,每个人都知道,我知道,我一直使用它们,我知道它们比原始指针好多少,但有时它是完全安全的使用原始指针..为什么不呢?

让我们把问题反过来看。有时使用原始指针是安全的。这就是使用它们的理由吗?关于原始指针实际上有什么吗?superior到智能指针?这取决于。Some智能指针类型比原始指针慢。其他人则不然。使用原始指针而不是指针的性能原理是什么?std::unique_ptr or a boost::scoped_ptr?它们都没有任何开销,它们只是提供更安全的语义。

这并不是说您永远不应该使用原始指针。只是你不应该仅仅因为你认为你需要性能,或者仅仅因为“它看起来安全”而这样做。当您需要表示智能指针无法表示的内容时,请执行此操作。根据经验,使用指针来指向事物,并使用智能指针来获取所有权东西的。但这是一个经验法则,而不是普遍规则。使用适合手头任务的任何一个。但不要盲目地认为原始指针会更快。当您使用智能指针时,请确保您熟悉它们。太多人只是用shared_ptr对于所有事物,这都太糟糕了,无论是在性能方面还是在最终应用于所有事物的非常模糊的共享所有权语义方面。

不要使用按位运算 - 太 C 风格?啥?当你确定自己在做什么时为什么不呢?例如 - 不要按位交换变量 ( a ^= b; b ^= a; a ^= b; ) - 使用标准的三步交换。不要使用左移来乘以二。等等,等等(好吧,这不是 C++ 风格与 C 风格的对比,但仍然“不是很好的做法”)

那是正确的。原因是“它更快”。按位交换在很多方面都存在问题:

  • 在现代 CPU 上速度较慢
  • 它更微妙,更容易出错
  • 它适用于非常有限的类型

当乘以二时,乘以二。编译器知道这个技巧,并且会应用它如果更快的话。再次,转变也存在许多相同的问题。在这种情况下,它可能会更快(这就是编译器会为您执行此操作的原因),但它仍然更容易出错,并且它适用于有限的类型集。特别是,它可能可以与您的类型一起编译良好think这样做是安全的……然后在实践中爆炸。特别是,负值上的位移位是一个雷区。让编译器为您导航。

顺便说一下,这与“C 风格”无关。完全相同的建议也适用于 C。在 C 中,定期交换是still比按位破解更快,并且位移而不是乘法将still如果它有效并且速度更快,则由编译器完成。

但作为一名程序员,您应该仅将按位运算用于一件事:对整数进行按位操作。你已经有了一个乘法运算符,所以使用that当你想繁殖的时候。而且你还有一个std::swap功能。如果您想交换两个值,请使用它。也许令人惊讶的是,优化时最重要的技巧之一是编写可读的、有意义的代码。这使您的编译器能够理解代码并对其进行优化。std::swap可以专门针对其所使用的特定类型进行最有效的交换。并且编译器知道几种实现乘法的方法,并且会根据情况选择最快的一种......如果你告诉它的话。如果你告诉它进行位移位,那么你只是在误导它。告诉它乘法,它会给你最快的乘法。

最后,最昂贵的 - “不要使用 enum-s 返回代码,它太 C 风格,对不同的错误使用异常”?

取决于你问的是谁。我认识的大多数 C++ 程序员都为这两者找到了空间。但请记住,返回码的一件不幸的事情是它们很容易被忽略。如果这是不可接受的,那么也许您应该在这种情况下选择例外。还有一点是,RAII 与异常一起工作效果更好,而且 C++ 程序员绝对应该尽可能使用 RAII。不幸的是,由于构造函数无法返回错误代码,因此异常通常是指示错误的唯一方法。

但仍然..性能怎么样?

那又怎样呢?任何正派的 C 程序员都会很乐意告诉您不要过早优化。

您的 CPU 每秒可能可以执行 80 亿条指令。如果您拨打两次电话std::stringstream在那一刻,这会对预算产生明显的影响吗?

您无法预测性能。您无法制定能够产生快速代码的编码指南。即使你从不抛出任何异常,也从不使用stringstream,你的代码仍然不会自动变快。如果您在编写代码时尝试进行优化,那么您将花费 90% 的精力来优化几乎从未执行过的 90% 的代码。为了获得可衡量的改进,您需要关注占执行时间 95% 的 10% 的代码。试图使一切快速只会导致浪费大量时间而几乎没有什么用处,并且代码库也变得更加丑陋。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 风格与性能? 的相关文章

随机推荐

  • NoReverseMatch at / urlresolvers 的反向错误,get_absolute_url()

    函数 get absolute url 中 url reverse 出错 无法反转每个模型 serial slug 中的 url 但 url 本身存在 这是主 url py from django conf urls import incl
  • Android并发使用[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Android 有许多不同的便利措施可以在单独的线程上同时执行代码 但我不确定何时应该使用每种方法 或者这些不同方法的最佳实践是什么
  • 打印数组值两次 / php 和 pdo

    我收到 field value 两次 但为什么呢 正常的结构是
  • 在ggplot2散点图中使用伪彩色来表示密度

    有人知道如何创建像屏幕截图中那样的图表吗 我试图通过调整 alpha 来获得类似的效果 但这会使异常值几乎看不见 我只从一个名为 FlowJo 的软件中知道这种类型的图 这里他们将其称为 伪彩色点图 不确定这是否是官方术语 我想专门在 gg
  • ng-click 在动态创建的内容中不起作用

    我在 Angular 中有这个功能 我在其中添加了一个带有 ng click 的新幻灯片 var addSlide function scope slideIndex event slideIndex var slider angular
  • 通过 PHP 批量插入 MySQL 数据库会跳过名称

    我目前正在开发一个跟踪程序 可以同时跟踪数百个用户 但我遇到了一个有点烦人的问题 我让用户插入数据库的方法是通过 html 文本区域 然后将它们作为参数发送 总是有大约 60 人中的 7 人 也总是相同的名字 被插入到数据库中 但它没有插入
  • 创建具有不同单元格类型的分组 UITableview

    我需要创建一个分组的 uitableview 其中包括一些部分以及每个部分中可能不同的单元格类型 我正在尝试创建类似旧的 foursquare 应用程序 用户页面 包括 排行榜 朋友建议 朋友 统计数据 最探索的类别 部分 我对 ios 编
  • ASP.NET MVC 客户端验证

    我热衷于使用 ASP NET MVC 但我希望改进的领域之一是客户端验证 我知道最新版本 预览版 5 有很多用于验证的新功能 但它们似乎都是在页面发布之后 我看过一篇有趣的文章史蒂夫 桑德森 http blog codeville net
  • 没有这样的模块 Crashlytics - Pod 似乎丢失了

    我经常收到错误 No such module Crashlytics 我通常会花费数小时清理构建文件夹 重新安 装所有内容 运行 pod install 等来解决该问题 但我对此感到厌倦 并希望一劳永逸地解决该问题 我的 podfile 包
  • Mongoose 验证外键(参考)

    我尝试了几种不同的方法来验证 Mongoose 中的外键 但无法弄清楚 我有一个这样的架构 Doctors js var schema mongoose Schema email type String module exports mon
  • 使用 Django 上传表单清空 Request.FILES

    尝试使用非常简单的形式将文件上传到新的类实例中 我希望这两个文件都在request FILES但它是空的 我在捆绑的开发服务器上 被困在这里并解决了所有相关问题 wayfinder map media file request FILES
  • 复选框样式并使其选中

    从数据库检索到的复选框太长了 它是向下的 有什么办法使它成为四层 单击 所有字段 复选框时 必须选中所有复选框 这要怎么做呢 我的代码 protected function getConfigForm sql SELECT id order
  • 检查字符串中的字符是否都是唯一的

    我正在尝试使用 JS 通过数组来解决这个问题 var str abcdefgh for i 0 i lt 255 i arr i false function check for i 0 i lt str length i if arr s
  • 如何从实体管理器获取 jpa 数据源属性

    大家好 我想知道是否可以通过实体管理器获取数据库连接属性 我的 persistence xml 看起来像这样
  • 暂停事件在 PhoneGap iPhone 中无法正常工作?

    这是我的代码 This is an event that fires when a PhoneGap application is put into the background document addEventListener paus
  • Go 语言中的打印格式列表

    只是想知道使用 fmt 包的功能的打印格式列表 例如 v 用于打印值 T 可以打印值的类型 还有什么 动词 格式列表可在fmt 包的文档 http golang org pkg fmt General v the value in a de
  • 如何在.net6中使用WebApplicationFactory(没有可讲的入口点)

    在 ASP NET Core 6 中 默认模板将所有内容从Startup cs into Program cs 并使用 Program cs 中的顶级语句 因此不再有 可以说的 Program乙醚类 这看起来很棒 但现在 我需要测试所有这些
  • 在快速解析 Json 时无法将“NSNull”类型的值转换为“NSString”

    我有以下课程 class BannerResponse NSObject let URL Url let CONTACT NO ContactNo let IMAGE Image let BIG IMAGE BigImage let ID
  • 为什么 Evan 的调试器说我要转向 eax 而不是 rax?

    我正在将一些值移至 rax 但调试器显示它正在移至 eax 这是怎么回事 是用调试器 nasm 还是我的知识 无论如何 代码当然可以完美运行 我使用的调试器是 Evan s Debugger 简而言之 您和调试器都是正确的 当您将某物移动到
  • C++ 风格与性能?

    C 风格与性能 使用 C 风格的东西 比某些 C 等价物更快 这是不好的做法吗 例如 不要使用atoi itoa atol ETC 使用std stringstream 永远不要使用原始指针 而是使用智能指针 好吧 它们真的很有用 每个人都