我刚刚证明了埃拉托斯特尼筛法的效率低于试除法吗?

2023-12-24

我试图比较两种算法的运行时速度:一个用于打印素数(10,000 个数字)的强力 C 程序,以及一个埃拉托斯特尼筛法 C 程序(也是 10,000 个素数)。

我测量的筛子算法的运行时间是:0.744 秒

我测量的暴力算法的运行时间是:0.262 秒

然而,我被告知埃拉托色尼筛法比暴力法更有效,所以我认为它可以运行faster。所以要么我错了,要么我的程序有缺陷(我对此表示怀疑)。

因此,我的问题是:既然我得到了与我预期相反的结果,这是否证明埃拉托斯特尼筛确实是less与试除法相比,算法在速度方面是否高效?

我不确定它是否有任何相关性,但我正在使用 Dev C++ 编译器和 Windows 7。


TL;DR:仅比较一种输入大小的代码变体的速度是没有意义的;比较经验增长阶数真实反映算法的代码的性质,并且对于输入大小的相同测试范围,在不同的测试平台上将保持一致。比较绝对速度值仅对于表现出相同渐近或至少局部增长行为的代码变体有意义。


仅在一种输入大小下测量两种实现的速度是不够的。通常需要多个数据点来评估运行时间经验增长阶数 http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth我们的代码(因为代码可以使用不同的输入大小运行)。它是基于输入大小比率的运行时间比率的对数。

所以即使在某些输入code_1 runs 10code_2,但是它的运行时间doubles输入大小每次加倍,而对于code_2它只会增长1.1x, 很快code_2会变得比code_1.

所以衡量一个算法效率的真正标准是它的运行时复杂度 http://en.wikipedia.org/wiki/Time_complexity(以及其空间的复杂性,即内存要求)。当我们凭经验测量它时,我们只测量手头的特定代码(在特定的输入大小范围内),而不是测量算法本身,即它的理想实现。

特别地,试除法的理论复杂度为O(n^1.5 / (log n)^0.5), in n产生的素数,通常被视为~ n^1.40..1.45经验增长顺序(但可以是~n^1.3最初,对于较小的输入大小)。对于埃拉托斯特尼筛来说是O(n log n log (log n)),通常被视为~ n^1.1..1.2。但肯定存在试除法和埃拉托色尼筛的次优实现,其运行速度为~n^2.0更糟糕的是。

So no,这证明不了什么。一个数据点毫无意义,至少三个需要获得“大局”,即能够predict可以肯定的是,更大的输入大小所需的运行时间/空间。

预言已知的确定性是科学的方法 http://en.wikipedia.org/wiki/Scientific_method就是这样。


顺便说一句,你的运行时间很长。 10,000 个素数的计算应该几乎是瞬时的,对于在快速机器上运行的 C 程序来说,远小于 1/100 秒。也许您也在测量打印时间。不。 :)

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

我刚刚证明了埃拉托斯特尼筛法的效率低于试除法吗? 的相关文章

  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • fgets() 和 Ctrl+D,三次才能结束?

    I don t understand why I need press Ctrl D for three times to send the EOF In addition if I press Enter then it only too
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • C# 中可空类型是什么?

    当我们必须使用nullable输入 C net 任何人都可以举例说明 可空类型 何时使用可空类型 https web archive org web http broadcast oreilly com 2010 11 understand
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 基于范围的 for 循环中的未命名循环变量?

    有没有什么方法可以不在基于范围的 for 循环中 使用 循环变量 同时也避免编译器发出有关未使用它的警告 对于上下文 我正在尝试执行以下操作 我启用了 将警告视为错误 并且我不想进行像通过在某处毫无意义地提及变量来强制 使用 变量这样的黑客
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 使用安全函数在 C 中将字符串添加到字符串

    我想将文件名复制到字符串并附加 cpt 但我无法使用安全函数 strcat s 来做到这一点 错误 字符串不是空终止的 我确实设置了 0 如何使用安全函数修复此问题 size strlen locatie size nieuw char m
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • .NET 选项将视频文件流式传输为网络摄像头图像

    我有兴趣开发一个应用程序 它允许我从 xml 构建视频列表 包含视频标题 持续时间等 并将该列表作为我的网络摄像头流播放 这意味着 如果我要访问 ustream tv 或在实时通讯软件上激活我的网络摄像头 我的视频播放列表将注册为我的活动网
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • 方法参数内的变量赋值

    我刚刚发现 通过发现错误 你可以这样做 string s 3 int i int TryParse s hello out i returns false 使用赋值的返回值是否合法 Obviously i is but is this th

随机推荐