首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么不对所有球拍中的人进行序列功能呢?

为什么不对所有球拍中的人进行序列功能呢?
EN

Stack Overflow用户
提问于 2016-08-19 19:33:50
回答 1查看 91关注 0票数 1

在球拍中使用序列长度、序列引用、序列映射等,而不是对列表(长度列表-引用等)、字符串(字符串长度、字符串-引用等)、向量等使用不同的函数,有什么缺点吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-19 20:06:06

性能.

考虑一下这个小小的基准:

代码语言:javascript
运行
AI代码解释
复制
#lang racket/base

(require racket/sequence)

(define len 10000)
(define vec (make-vector len))

(collect-garbage)
(collect-garbage)
(collect-garbage)

(time (void (for/list ([i (in-range len)])
              (vector-ref vec i))))

(collect-garbage)
(collect-garbage)
(collect-garbage)

(time (void (for/list ([i (in-range len)])
              (sequence-ref vec i))))

这是我机器上的输出:

代码语言:javascript
运行
AI代码解释
复制
; vectors (vector-ref vs sequence-ref)
cpu time: 1 real time: 1 gc time: 0
cpu time: 2082 real time: 2081 gc time: 0

是的,相差三个数量级。

为什么?嗯,racket/sequence并不是一个非常“聪明”的API,即使向量是随机访问,sequence-ref也不是。结合Racket优化器对原始操作进行严重优化的能力,sequence是一个非常糟糕的接口。

当然,这有点不公平,因为向量是随机访问的,而像列表这样的东西则不是。然而,执行与上面的测试完全相同的测试,但使用列表而不是向量仍然会产生相当可怕的结果:

代码语言:javascript
运行
AI代码解释
复制
; lists (list-ref vs sequence-ref)
cpu time: 113 real time: 113 gc time: 0
cpu time: 1733 real time: 1732 gc time: 0

序列API是缓慢的,主要是由于高度的间接。

现在,性能本身并不是直接拒绝API的理由,因为在更高层次的抽象中工作有具体的优势。尽管如此,我认为序列API不是一个很好的抽象,因为它:

  1. …在其实现中是不必要的有状态的,这给接口的实现者带来了不必要的负担。
  2. …不适合与列表不相似的内容,如随机访问向量或哈希表。

如果您想使用更高级别的API,一种可能的选择是使用 package,它尝试提供类似于racket/sequence的API,但可以容纳更多类型的数据结构,并且具有更完整的功能集。免责声明:我是collections软件包的作者。

考虑到上面的基准,性能仍然比直接使用底层函数差,但至少更易于管理:

代码语言:javascript
运行
AI代码解释
复制
; vectors (vector-ref vs ref)
cpu time: 2 real time: 1 gc time: 0
cpu time: 97 real time: 98 gc time: 10

; lists (list-ref vs ref)
cpu time: 104 real time: 103 gc time: 0
cpu time: 481 real time: 482 gc time: 0

你是否负担得起费用取决于你到底在做什么,这取决于你自己打电话。只要执行某种动态调度,专门操作总是比服从它们的操作要快一些。和往常一样,记住性能优化的规则:不要猜测,度量。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39050201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档