为什么 strcmp 比我的函数快得多?

2024-02-19

我写了一个函数,Str::Compare,这基本上是一个strcmp以另一种方式重写。 在比较两个函数时,在循环中重复 500'000'000 次,strcmp执行速度太快,大约x750快几倍。

这段代码是在 C 库中编译的-Os参数有效:

int Str::Compare(char* String_1, char* String_2)
{
    char TempChar_1, TempChar_2;

   do
   {
        TempChar_1 = *String_1++;
        TempChar_2 = *String_2++;
   } while(TempChar_1 && TempChar_1 == TempChar_2);

   return TempChar_1 - TempChar_2;
}

该函数的执行时间是3.058s, while strcmp only 0.004s.

为什么会发生这种情况?

这也是我实现基准循环的方式:

int main()
{
     char Xx[] = {"huehuehuehuehuehuehuehuehuehuehuehuehuehue"},
          Yy[] = {"huehuehuehuehuehuehuehuehuehuehuehuehuehue"};
     for(int i = 0; i < 500000000; ++i)
         Str::Compare(Xx, Yy);
}

Edit: 在测试我编写的一些代码和优化时,效果显着提高Str::Compare速度。 如果之前strcmp was x750现在只快了几倍x250。这是新代码:

int Str::Compare(char* String_1, char* String_2)
{
     char TempChar_1, TempChar_2, TempChar_3;

     while(TempChar_1 && !TempChar_3)
     {
          TempChar_1 = *String_1++;
          TempChar_2 = *String_2++;
          TempChar_3 = TempChar_1 ^ TempChar_2;
     }

     return TempChar_1 - TempChar_2;
}

新的执行时间是0.994s.


我对此很好奇并构建了一个测试程序:

#include <string.h>

compare(char* String_1, char* String_2)
{
    char TempChar_1,
         TempChar_2;

   do
   {
        TempChar_1 = *String_1++;
        TempChar_2 = *String_2++;
   } while(TempChar_1 && TempChar_1 == TempChar_2);

   return TempChar_1 - TempChar_2;
}


int main(){
    int i=strcmp("foo","bar");
    int j=compare("foo","bar");

    return i;
}

我将它编译为汇编程序gcc -S -Os test.c使用 gcc 4.7.3 生成以下汇编程序:

    .file   "test.c"
    .text
    .globl  compare
    .type   compare, @function
compare:
.LFB24:
    .cfi_startproc
    xorl    %edx, %edx
.L2:
    movsbl  (%rdi,%rdx), %eax
    movsbl  (%rsi,%rdx), %ecx
    incq    %rdx
    cmpb    %cl, %al
    jne .L4
    testb   %al, %al
    jne .L2
.L4:
    subl    %ecx, %eax
    ret
    .cfi_endproc
.LFE24:
    .size   compare, .-compare
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "bar"
.LC1:
    .string "foo"
    .section    .text.startup,"ax",@progbits
    .globl  main
    .type   main, @function
main:
.LFB25:
    .cfi_startproc
    movl    $.LC0, %esi
    movl    $.LC1, %edi
    call    compare
    movl    $1, %eax
    ret
    .cfi_endproc
.LFE25:
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3"
    .section    .note.GNU-stack,"",@progbits

我不太擅长 x86 汇编程序,但据我所知,对 strcmp 的调用被删除并简单地替换为常量表达式(movl $1, %eax)。因此,如果您在测试中使用常量表达式,gcc 可能会将 strcmp 优化为常量。

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

为什么 strcmp 比我的函数快得多? 的相关文章

  • 计算 Richtextbox 中所有单词的最有效方法是什么?

    我正在编写一个文本编辑器 需要提供实时字数统计 现在我正在使用这个扩展方法 public static int WordCount this string s s s TrimEnd if String IsNullOrEmpty s re
  • ClickOnce 应用程序错误:部署和应用程序没有匹配的安全区域

    我在 IE 中使用 FireFox 和 Chrome 的 ClickOnce 应用程序时遇到问题 它工作正常 异常的详细信息是 PLATFORM VERSION INFO Windows 6 1 7600 0 Win32NT Common
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 使用接口有什么好处?

    使用接口有什么用 我听说它用来代替多重继承 并且还可以用它来完成数据隐藏 还有其他优点吗 哪些地方使用了接口 程序员如何识别需要该接口 有什么区别explicit interface implementation and implicit
  • 回发后刷新时提示确认表单重新提交。我做错了什么?

    我有一个以空白 默认状态启动的仪表板 我让用户能够将保存的状态加载到仪表板中 当他们单击 应用 按钮时 我运行以下代码 function CloseAndSave var radUpload find radUpload1ID var in
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 如何在 32 位或 64 位配置中以编程方式运行任何 CPU .NET 可执行文件?

    我有一个可在 32 位和 64 位处理器上运行的 C 应用程序 我试图枚举给定系统上所有进程的模块 当尝试从 64 位应用程序枚举 32 位进程模块时 这会出现问题 Windows 或 NET 禁止它 我认为如果我可以从应用程序内部重新启动
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • 如果 PyPy 快 6.3 倍,为什么我不应该使用 PyPy 而不是 CPython?

    我已经听到很多关于PyPy http en wikipedia org wiki PyPy项目 他们声称它比现有技术快 6 3 倍CPython http en wikipedia org wiki CPython口译员开启他们的网站 ht
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • Cmake 链接共享库:包含库中的头文件时“没有这样的文件或目录”

    我正在学习使用 CMake 构建库 构建库的代码结构如下 include Test hpp ITest hpp interface src Test cpp ITest cpp 在 CMakeLists txt 中 我用来构建库的句子是 f
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • 无法接收 UDP Windows RT

    我正在为 Windows 8 RT 编写一个 Windows Store Metro Modern RT 应用程序 需要在端口 49030 上接收 UDP 数据包 但我似乎无法接收任何数据包 我已按照使用教程进行操作DatagramSock
  • 如何将 PostgreSql 与 EntityFramework 6.0.2 集成? [复制]

    这个问题在这里已经有答案了 我收到以下错误 实体框架提供程序类型的 实例 成员 Npgsql NpgsqlServices Npgsql 版本 2 0 14 2 文化 中性 PublicKeyToken 5d8b90d52f46fda7 没
  • 当我使用 OpenSSL1.1.0g 根据固定的 p 和 g 值创建 Diffie Hellman 密钥协议密钥时,应该执行哪些检查?

    您好 我尝试通过这段代码使用修复 p 和 g 参数来制作 Diffie Hellman Keysanswer https stackoverflow com a 54538811 4706711 include

随机推荐

  • 使用 Tensorflow 可以实现增量学习吗?

    我正在尝试使用非常大的数据集 比我的记忆大得多 训练 Tensorflow 模型 为了充分利用所有可用的训练数据 我正在考虑将它们分成几个小 碎片 并一次在一个碎片上进行训练 经过一番研究 我发现这种方法通常被称为 增量学习 并基于这个维基
  • 我应该封装我的 IoC 容器吗?

    想要改进这篇文章吗 提供此问题的详细答案 包括引用和解释为什么你的答案是正确的 不够详细的答案可能会被编辑或删除 我正在尝试确定花费额外的精力来封装 IoC 容器是否有意义 经验告诉我 我应该在我的应用程序和任何第三方组件之间放置一层封装
  • 使用KafkaListener时,如何检查主题消息是否已读完?

    使用 KafkaListener时 如何检查主题消息是否已读完 See 这个答案 https stackoverflow com questions 55430893 how to check if kafka is empty using
  • 使用 * 和 & 比较值是否相等有什么区别?

    我想我在很高的水平上理解两者之间的区别 and Rust 中的内容与内存管理有关 下面的代码片段有什么区别 应用一种方法与另一种方法相比是否存在危险 for i item in bytes iter enumerate if item b
  • Spring JPA Projection 包括链接

    给定一个简单的 Event 模型 它具有一组 Booking 对象 Event Entity public class Event Id GeneratedValue strategy GenerationType AUTO private
  • 将 Google 字体与 Shadow DOM 结合使用 [重复]

    这个问题在这里已经有答案了 我正在尝试在内容脚本端的扩展中使用谷歌字体 我下载并从扩展目录加载的 Noto 字体可以工作 它也在 web accessible resources 中声明 并且在 ShadowDOM 中工作正常 但谷歌字体不
  • Maven 3/Mercury 的良好学习资源

    我一直在尝试了解有关 Maven 3 和 Mercury 的更多信息 Maven Mercury 是 Maven Artifact 子系统的替代品 并且完全替代现有传输的 HTTP HTTPS DAV DAVS 部分 目前似乎可用的实质性内
  • 点阵图条件填充颜色

    Problem 我有一个数据框 我想用lattice的面板点图 不是ggplot2 对其进行可视化 它包含一个变量 应有条件地使用该变量通过不同的颜色填充突出显示数据 可重现的例子 require lattice Make reproduc
  • imp.load_source 方法的第一个参数有什么作用?

    我正在阅读this https stackoverflow com questions 67631 how to import a module given the full path关于从绝对路径导入模块的问题 答案建议使用以下代码 im
  • 如何在 NHibernate 中对两个表进行并集?

    我需要使用 NHibernate 和 HQL 来合并两个表 我在网上找到的帮助很少 我想知道这是否可能 如果可能的话如何 找到了我的答案 http www hibernate org 117 html A21 http www hibern
  • 资源规格和代理跟踪

    我需要解决一个问题 但由于缺乏 Java 培训 我无法解决该问题 要编写什么代码来跟踪获取资源的代理 让我更好地解释一下 我有一系列房间 每个进入该结构的特工都会占用一个房间 并在整个住宿期间保留该房间 我想实时查看哪些房间被占用以及由哪个
  • Int32 的 GetHashCode() 是如何实现的?

    我到处找遍了 但什么也没找到 有人能解释一下吗 根据反射镜 public override int GetHashCode return this 有道理 不是吗
  • 工厂方法 (1) vs 工厂 (2) vs Builder (3) 模式

    用途 1 2 3 的用例是什么 使用它有什么优点和缺点 他们之间有什么区别 工厂方法模式 这种模式与工厂模式非常相似 客户端也从类层次结构中向工厂请求特定类型的对象 但是工厂模式的 Create 方法工厂类将特定对象的创建委托给派生类并返回
  • 如何从管道 (jenkinsfile) 中使用 Jenkins Copy Artifacts 插件?

    我试图找到一个在 Jenkins 管道 工作流程 中使用 Jenkins Copy Artifacts 插件的示例 谁能指出使用它的示例 Groovy 代码吗 通过声明式 Jenkinsfile 您可以使用以下管道 pipeline age
  • 超时已过。操作完成前超时时间已过或服务器未响应

    运行 ssis 包时 我在 ADO net 源中调用 sp 但出现此错误 超时已过 操作完成之前超时时间已过 或者服务器没有响应 我已将命令超时设置为 0 无限时间 但仍然收到错误 sp 在 sql server 中工作正常 大约需要 31
  • Android Studio 签名的 APK 未安装

    我在 Android Studio 中 在 构建 gt 生成签名的 APK 下签署 APK 并使用向导 一切似乎都正常 并生成了一个 apk 文件 当我将此文件复制到我的设备 Nexus 7 或 Moto X 时 它不会安装 我收到 安装失
  • 单击电子邮件链接时出现不受支持的操作错误

    我已在 xml 中提供了指向 TextView 的电子邮件链接 但当我单击 TextView 时 它显示不支持的操作错误 如何将活动链接放在文本视图中的电子邮件上 这是我的 string xml 文件的代码
  • 如何禁用 UIScrollView 的水平滚动?

    我有一个UIView就像iPhone的跳板一样 我已经使用创建它UIScrollView and UIButtons 我想禁用所述滚动视图上的水平滚动 我只想要垂直滚动 我该如何实现这个目标 你必须设置contentSize的财产UIScr
  • Akka/Java getContext().become 带参数?

    在 Akka Scala 中 可以将参数传递给自定义接收函数 因此可以通过 params 传递整个 actor 状态 而无需使用可变变量 context become myCustomReceive param1 param2 但在 Jav
  • 为什么 strcmp 比我的函数快得多?

    我写了一个函数 Str Compare 这基本上是一个strcmp以另一种方式重写 在比较两个函数时 在循环中重复 500 000 000 次 strcmp执行速度太快 大约x750快几倍 这段代码是在 C 库中编译的 Os参数有效 int