B 树与二叉树

2024-01-03

如果我使用 b 树实现内存(RAM)搜索操作,那么与二叉树相比,它在缓存或其他一些效果方面会更好吗?

我所知道的是——

binary search tress---O(log n)
btrees ---------------O(c log n)

各种博客上对此进行了很多讨论。


Algorithmic complexity is the same, since O(logb n) = O(c log n) = O(log n) but the constant factors, which are hidden in big-O notation, could vary noticeably, depending on implementation and hardware.

B 树是为盘片硬盘设计的,它具有较长的访问时间(将磁头移动到位),然后读取整个物理扇区。使 B 树节点与扇区一样大可以最大限度地减少访问次数,并最大限度地提高每次读取操作的有用数据。

但是,如果您的内存不足,则访问时间可以忽略不计,因此更好的比较是计算算法访问的单个单词的数量。

For example, let's plan a data structure to store 220 keys of 1 word each, for a total of 4MiB of raw data on a 32bit machine.

A binary search tree will have 220 nodes, each holding one key and two pointers (3 words). Depth will be log2(220) = 20. The average search will have to read the key and one of the pointers from each node in its path, from the root all the way down = 40 words.

A B-tree made for hard disks will have 4kB nodes. Each node could be stored internally as a sorted array of key and pointer couples, between 256 and 512 of them. What is the average search going to look like? Considering an average 3/4 fill, each node will contain 384 entries, and its internal binary search will have to visit on average log2(384) = 5.95 keys. The average depth will be log384(220) = 2.33, so our search will have to read on average 2.33 times 5.95 keys, or about 14 words.

In the case of a low-fanout (branching factor) B-tree, with each node holding between 16 and 32 keys, the average fill will be 24 keys, the average depth log24(220) = 4.36, the binary search in each node will make log2(24) = 4.58 comparisons, and the overall average search will have to read about 20 words.

请记住,最后两个数据结构比二叉树获得了更好的结果,因为它们优化读取操作过度修改。要将键插入这些 B 树之一,您必须平均重写整个 384 字或 24 字节点(如果不超过一个),而在二叉树情况下,写入操作仍然只需要最多触摸 40 个单词。

(之前我错了。感谢@virco 和@Groo 在评论中指出我的错误。)

无论如何,看起来扇出较低的纯内存 B 树在实践中似乎比二叉树表现更好 http://panthema.net/2007/stx-btree/speedtest/.

每个节点 32 个密钥似乎是当前架构(32 位和 64 位)的最佳选择。许多较新的语言和库正在使用 32 键 B 树作为内置数据结构,与哈希表和数组一起使用或作为哈希表和数组的替代品。这种用法是由Clojure http://clojure.org/和其他函数式语言,但随后被 Javascript 等更主流的语言所采用,最近的重点是不可变数据结构(例如不可变.js https://facebook.github.io/immutable-js/)

这个结果不仅可以通过计算从内存读取的字数来解释,还可以通过高速缓存未命中来解释,高速缓存未命中是导致 CPU 停止并等待 RAM 的读取操作。如果缓存架构可以一次获取包含整个 B 树节点的 RAM 块,我们就可以获得与基于磁盘的大容量存储成功使用的相同优化。

在硬盘优化数据结构的情况下,我们将使用节点与物理磁盘扇区一样大的 B 树,以最大限度地减少磁盘访问时间。在本例中,我们使用 B 树,其节点与 3 级缓存对 RAM 执行的读取操作一样大,以最大限度地减少缓存未命中。

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

B 树与二叉树 的相关文章

  • Docker容器CPU使用率监控

    根据 docker 的文档 我们可以通过以下方式获取 docker 容器的 CPU 使用率码头工人统计命令 CPU 列将给出容器正在使用的主机 CPU 的百分比 假设我限制容器使用 50 的主机单个 CPU 我可以通过 cpus 0 5 选
  • 在用户提交的正则表达式中查找捕获组

    我有一个 python 应用程序 需要处理用户提交的正则表达式 出于性能考虑 我想禁止捕获组和反向引用 我的想法是使用另一个正则表达式来验证用户提交的正则表达式不包含任何命名或未命名的组捕获 如下所示 def validate user r
  • 为什么这个 Clojure 减速器 r/fold 没有提供任何性能优势?

    我想知道为什么下面的代码在 r fold 的情况下没有提供加速 我对减速器有什么误解吗 我在一个相当慢的 尽管有 2 个核心 Ubuntu 12 04 开发盒上运行它 通过 emacs 和 lein 运行 每个都有相同的结果 require
  • 如何加速Python循环

    我查看了几个网站上的一些讨论 但没有一个给我解决方案 这段代码运行时间超过5秒 for i in xrange 100000000 pass 我正在研究整数优化问题 我必须使用O n log n 算法编辑 O n 4 算法 其中n代表矩阵的
  • 在数据库中存储多维数组:关系数组还是多维数组?

    我读过很多类似的帖子多维到单维 多维数据库等等 但没有一个答案有帮助 我确实在谷歌上找到了很多文档 但只提供了背景信息 并没有回答手头的问题 我有很多彼此相关的字符串 PHP 脚本中需要它们 结构是分层的 这是一个例子 A AA AAA A
  • 使用 hisorian.py 时显示“找不到结束时间”

    我正在尝试收集我的应用程序的电池统计信息 运行指定的所有命令后http developer android com tools performance batterystats battery historian index html ht
  • 什么时候汇编比C更快? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的
  • 如何提高MySQL INSERT和UPDATE性能?

    我们数据库中的 INSERT 和 UPDATE 语句的性能似乎正在下降 并导致我们的 Web 应用程序性能不佳 表是InnoDB 应用程序使用事务 我可以做一些简单的调整来加快速度吗 我认为我们可能会遇到一些锁定问题 我怎样才能找到答案 你
  • MongoDB聚合查询性能提升

    我最近开始将数据从 Microsoft SQL Server 转移到 MongoDB 以获得可扩展性 就移民而言一切都很好 该文档有 2 个重要字段 customer timestamphash 年月日 我们在安装 MongoDB 的 Az
  • vm.dirty_ratio 和 vm.dirty_background_ratio 之间的区别?

    我目前正在试验中找到的内核参数 proc sys vm 尤其dirty ratio and dirty background ratio 内核文档对两者都有以下解释 脏背景比例 包含 以包含空闲页面的总可用内存的百分比表示 和可回收页 后台
  • 在二维平面中找到距离 P 点最近的 K 个点

    资料来源 亚马逊面试问题 解决方案1制作大小为 K 的堆并按最小距离收集点O NLogK 复杂 解决方案2 取大小为 N 的数组并按距离排序 应该使用QuickSort 霍尔修改 取前 K 点作为答案 这太复杂了 NlogN 但可以优化到近
  • Maven 依赖项更新报告需要数小时才能完成

    我有任务运行 Jenkins 工作女巫会报告新版本的库 我认为这些可以满足我的需要 org codehaus mojo versions maven plugin 2 5 plugin updates report org codehaus
  • CSS:它渲染“ul > li”比“ul li”更快吗?

    正如我从少数人那里听说的那样 使用 gt 而不是 使渲染速度更快 slide hover gt div gt span border color c8c8c8 OR slide hover div span border color c8c
  • jQuery UI .buttonset() 太慢

    我的 HTML 页面上有几千个按钮 运行需要10多秒 buttonset buttonset 文件准备好 有没有更快的方法来做到这一点 或者是我以某种方式限制按钮数量的唯一解决方案 创建buttonset在第一次显示之前按需进行 我刚刚测试
  • 如何有效地计算 Perl 中覆盖给定范围的范围?

    我有一个大约 30k 范围的数据库 每个范围都作为一对起点和终点给出 12 80 34 60 34 9000 76 743 我想编写一个 Perl 子例程来表示一个范围 不是来自数据库 并返回数据库中完全 包含 给定范围的范围数 例如 如果
  • 在 x86 ASM 中测试零通常哪个更快:“TEST EAX, EAX”与“TEST AL, AL”?

    测试 AL 中的字节是否为零 非零通常哪个更快 TEST EAX EAX TEST AL AL 假设之前有一个 MOVZX EAX BYTE PTR ESP 4 指令加载了一个带有零扩展的字节参数到 EAX 的其余部分 防止了我已经知道的组
  • 就性能而言,在页面上显示 1000 张图像的最佳方法是什么?

    我试图在一个页面上显示 1000 个相当小的图像 确实很多 但超出了我的控制范围 当一次性加载所有图像时 一次渲染 1000 张图像 性能显然会受到严重影响 我尝试在滚动时应用图像 src 大量 250px 滚动 25 个图像加载等 然后尝
  • 如果我将一个大函数声明为内联函数怎么办?

    我搜索了一些相关问题 例如C 中内联函数的好处 https stackoverflow com questions 145838 benefits of inline functions in c 但我还有疑问 如果内联函数只是为了 为编译
  • 我想优化这个短循环

    我想优化这个简单的循环 unsigned int i while j 0 j is an unsigned int with a start value of about N 36 000 000 float sub 0 i 1 unsig
  • 生成所有可能的树

    给定以下数据类型定义 data FormTree Empty Node FormTree FormTree deriving Show 我想编写一个函数 它生成一个无限列表 其中包含按长度排序的所有可能的树 例如节点数量 下面的代码几乎满足

随机推荐

  • 角度构建index.html不工作

    I have taken the build of angular project and got dist folder when i am trying to open the index html in browser I am ge
  • jqGrid 格式化程序和可排序列 - 不排序

    我正在为 jqGrid columnModel 使用自定义格式化程序 但无法使用格式化程序函数进行排序 如果我删除格式化程序列排序正常 jQuery listAgentOptions jqGrid height 240 datatype l
  • 可编码的失败初始化器

    我正在尝试解析以下项目数组的 json 模式 itemID 可能不为空 如何使项目的 ID 为零itemIDJSON 中不存在 itemID 123 itemTitle Hello 我的可解码类如下 public struct Item N
  • 我的所有视图控制器中都包含 AdMob 吗?

    我已经实施了 AdMob 一切似乎都正常 但我想知道 如何将横幅放入所有视图控制器中 目前 我仅在 RootViewController 上有横幅 我总共有 4 个视图控制器 Thanks 你想要的是一个GADBannerView各种单身人
  • 如何在spring 3.0中注册自定义PersistenceAnnotationBeanPostProcessor

    我想重写 PersistenceAnnotationBeanPostProcessor 它在插入 context component scan 标记后立即注册 我尝试注册一个同名的 bean 但 spring 仍然注册原始的后处理器 bea
  • 在 Eclipse Indigo 中运行 MPJ Express 时出现“未解决的编译问题”

    我遵循了 Youtube 上关于如何在 IDE 中使用 MPJ Express 运行并行应用程序的教程 我下载了最新版本的 MPJ Express 并使用了 Eclipse Indigo 我确实在我的项目 JAR 文件中包含了 MPI 当我
  • FXML 文档的 Netbeans 8.2 自动完成始终显示“无建议”

    我第一次在 Netbeans 8 2 中创建 JavaFX 项目 FXML 文档的自动完成功能始终显示 无建议 例如 我见过类似的问题 例如Netbeans7 1 和 JavaFX 2 0 FXML 代码完成不起作用 https stack
  • Gradle 6.0 打破了源集依赖

    我在这里为学生收集了一些课程 https github com emign engineEmi Lektionen tree master https github com emign engineEmi Lektionen tree ma
  • 在左下角/右下角创建两个按钮

    JButton button1 new JButton Button 1 JButton button2 new JButton Button 2 JFrame frame new JFrame frame getContentPane s
  • 引用 github 存储库中的 .css 文件作为 .html 文件中的样式表

    我在 github 上有一个存储库 其中有一个 css 文件 有什么方法可以让 github 以我可以在网页中使用它的方式提供该文件吗 换句话说 我希望能够从本地计算机或实时域上的 HTML 文件直接引用 github 上的此源文件 就像是
  • Java 中的贪吃蛇游戏,但我的重启按钮不起作用

    我的游戏重启按钮不起作用 点击它时它会倍增 我不太了解 Java 我认为自己很好 游戏主要内容 package snake game public class snake public static void main String arg
  • 选择各种嵌套容器中的最后一个元素

    如何选择 CSS 中最后一个也是最深的元素 有没有办法改进这个CSS代码 对于深树 您提出什么解决方案 15 25 我避免使用 JavaScript 但 SASS 解决方案是受欢迎的 也许使用 for level 1 div case gt
  • Dispatcher.BeginInvoke 问题

    我收到此代码的 非静态字段 方法或属性 System Windows Threading Dispatcher BeginInvoke System Action 需要对象引用 private void ResponseCompleted
  • 使用 AutoCloseable 关闭多个资源(try-with-resources)

    我知道 如果资源实现了 AutoCloseable 则您尝试传递的资源将自动关闭 到目前为止 一切都很好 但是 当我有多个想要自动关闭的资源时 我该怎么办 套接字示例 try Socket socket new Socket input n
  • 命名空间对性能有害吗? (PHP)

    我对 php 框架进行了一些更改以支持名称空间 但结果并不符合预期 对于简单的测试 主要加载框架类 执行时间减慢了约 10 根据您的经验 在大型应用程序上使用命名空间是否值得 考虑PHP的实际开发水平 已接受的答案php 命名空间基准测试
  • AWS将elb的8000端口转发到EC2的8000端口

    我有一个 ELB 其中在目标组中注册了多个 EC2 实例 我正在使用一个运行正常的 php 应用程序端口 它有 SSL 我想将端口 8000 用于我的节点应用程序 我想做的是将 my elb address 8000 转发到 any ec2
  • 根据元组的值对Python中的元组进行排序[重复]

    这个问题在这里已经有答案了 我正在尝试使用以下代码打印最常见的 10 个单词 但是 它不起作用 关于如何修复它有什么想法吗 def reducer count words self word counts send all num occu
  • 关于搜索引擎抓取我应该了解什么?

    我指的不是 SEO 的事情 我应该知道什么 例如 引擎运行 JavaScript 吗 他们使用cookies吗 cookie 是否会跨爬行会话进行 例如今天的 cookie 和下周或下个月的爬行 选定的 JS 过滤器是否因某种原因未加载 例
  • 请解释一下该程序中的逗号运算符

    请解释一下该程序的输出 int main int a b c d a 10 b 20 c a b d a b printf nC d c printf nD d d 我得到的输出是 C 10 D 20 我的疑问是 运算符在这里做什么 我使用
  • B 树与二叉树

    如果我使用 b 树实现内存 RAM 搜索操作 那么与二叉树相比 它在缓存或其他一些效果方面会更好吗 我所知道的是 binary search tress O log n btrees O c log n 各种博客上对此进行了很多讨论 Alg