python 中更快的分数模块

发布于 2024-12-26 14:20:28 字数 120 浏览 6 评论 0原文

是否有更快的 Fractions 模块,例如 cFractions 模块,就像有一个更快的 cDecimal 模块一样Decimal 模块的? fractions 模块太慢。

Is there a faster equivalent of the fractions module, something like a cFractions module, just as there is a cDecimal module, which is a faster equivalent of the Decimal module ? The fractions module is too slow.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我还不会笑 2025-01-02 14:20:28

我也因缺少这个包而苦苦挣扎,并决定实现一个名为 cfractions< /a> (源代码Github 上)。

我们唯一需要的就是安装它

/path/to/python3 -m pip install cfractions

,然后在模块中将 fractions 替换为 cfractions ,就这么简单。

主要特点包括

  • 内存更少

    <前><代码>>>>从 cffractions 导入分数
    >>>>>导入系统
    >>>>> sys.getsizeof(分数())
    32

    相比

    <前><代码>>>>从分数导入分数
    >>>>>导入系统
    >>>>> sys.getsizeof(分数())
    48

    所以它基本上是一个简单的 Python object + 2 分子和指针。分母。

  • 更快的速度:

    • 由一对int构造
      构造自整数对
    • 由单个浮点构建
      构造自单浮点
    • str 构建
      构造自str
    • n 个实例的总和
      总和n 个实例
    • n 个实例的乘积
      产品n 个实例
      或者如果我们看一下相对表现
      相关产品n 个实例
      我们可以看到 fractions.Fraction 飙升,耶!

    注意:我正在使用 perfplot 包< /a>,所有基准测试都在 Python3.9.4 上运行。


  • Python3.5+支持,

  • 纯 Python C API,无额外依赖项,

  • 由分子/分母对构造,单个int/float/任何numbers.Rational值, str (来自 版本1.4.0),

  • 充满恐惧算术&比较操作,

  • 字符串表示(__repr____str__),

  • pickleing 和 copying,

  • 不变性和复制ing可散列性,

  • 使用 intfloat 进行操作(对于后者,将 Fraction 实例转换为 float,就像 fractions.Fraction 一样),

  • PyPy 支持(通过回退到 fractions.Fraction 代理),

  • 使用 假设框架

它不包括

  • 复杂的操作。

I was struggling with lack of this package as well and decided to implement one called cfractions (source code available on Github).

The only thing we need is to install it

/path/to/python3 -m pip install cfractions

and after that replace fractions with cfractions in your modules, as easy as that.

Main features include

  • less memory

    >>> from cfractions import Fraction
    >>> import sys
    >>> sys.getsizeof(Fraction())
    32
    

    compared to

    >>> from fractions import Fraction
    >>> import sys
    >>> sys.getsizeof(Fraction())
    48
    

    so it's basically a plain Python object + 2 pointers for numerator & denominator.

  • more speed:

    • construction from pair of int
      construction from pair of integers
    • construction from single float
      construction from single float
    • construction from str
      construction from str
    • sum of n instances
      sum of n instances
    • product of n instances
      product of n instances
      or if we take a look at relative performance
      relative product of n instances
      we can see fractions.Fraction skyrocketing, yay!

    Note: I'm using perfplot package, all benchmarks run on Python3.9.4.

  • Python3.5+ support,

  • plain Python C API, no additional dependencies,

  • constructing from numerator/denominator pair, single int/float/any numbers.Rational value, str (from version 1.4.0),

  • full spectre of arithmetic & comparison operations,

  • string representation (both __repr__ & __str__),

  • pickleing and copying,

  • immmutability & hashability,

  • operating with int and float (with conversion of Fraction instance to float for the latter, as it is for fractions.Fraction),

  • PyPy support (by falling back to fractions.Fraction proxy),

  • property-based tests of all operations using Hypothesis framework.

What it doesn't include

  • operating with complex.
孤单情人 2025-01-02 14:20:28

使用 http://code.google.com/p/gmpy/

它使用 GMP 多重-用于快速整数和有理算术的精度库。

注意:我也是维护者。

Use http://code.google.com/p/gmpy/

It uses the GMP mutliple-precision library for fast integer and rational arithmetic.

Note: I'm also the maintainer.

雨巷深深 2025-01-02 14:20:28

不幸的是,如果不需要编译的外部依赖项,就没有可用的 c 等效项。根据您的需求,我提出的要点: https://gist.github.com/mscuthbert/f22942537ebbba2c31d4 可能会有所帮助。

它公开了一个函数 opFrac(num),该函数可以选择将 int、float 或 Fraction 转换为具有分母限制的 float 或 Fraction(我使用 65535,因为我正在处理小分数);如果浮点数可以精确地用二进制表示(即,它是两个分母的某个幂的倍数),那么就不用管它了。否则它将其转换为分数。类似地,如果分数可以用二进制精确表示,我们将其转换为浮点数;否则我们就不管它了。

Fraction(float).limit_denominator(x) 调用被提取到辅助函数 _preFracLimitDenominator 中,该函数仅创建一个 Fraction 对象,而不是通常通过调用创建的三个。

这一要点的用例很少,但只要存在,结果就会非常惊人。对于我的项目 music21,我们主要使用通常放置在节拍(整数)或二分之一、四分之一、八分之一等节拍(完全可以用二进制表示)上的音符,但在极少数情况下,音符有放置(偏移)或持续时间,即节拍的 1/3 或 1/5,我们遇到了大的浮点转换问题,导致了模糊的错误。我们的测试套件使用浮点偏移和持续时间运行了 350 秒。将所有内容都切换为分数会使时间增加到 1100 秒——完全不可接受。切换到可选的分数并快速创建分数将时间缩短至 360 秒,或者说性能仅下降了 3%。

如果您有时可以处理浮点数,有时可以处理分数,那么这可能是正确的选择。

Unfortunately, there's no c equivalent available without needing a compiled external dependency. Depending on your needs, the gist I've made: https://gist.github.com/mscuthbert/f22942537ebbba2c31d4 may help.

It exposes a function opFrac(num) that optionally converts an int, float, or Fraction into a float or Fraction with a denominator limit (I use 65535 because I'm working with small fractions); if the float can be exactly represented in binary (i.e., it's a multiple of some power of two denominator), it leaves it alone. Otherwise it converts it to a Fraction. Similarly, if the Fraction is exactly representable in binary we convert it to a float; otherwise we leave it alone.

The Fraction(float).limit_denominator(x) call is extracted out into a helper function, _preFracLimitDenominator, that only creates one Fraction object rather than the three normally created with the call.

The use cases for this gist are pretty few, but where they exist, the results are spectacular. For my project, music21, we work mostly with notes that are generally placed on a beat (integer) or on a half, quarter, eighth, etc. beat (exactly representable in binary), but on the rarer occasions when notes have placement (offset) or duration that is, say, 1/3 or 1/5 of a beat, we were running into big floating point conversion problems that led to obscure bugs. Our test suite was running in 350 seconds using floating point offsets and durations. Switching everything to Fractions ballooned the time to 1100 seconds -- totally unacceptable. Switching to optional Fractions with fast Fraction creation brought the time back to 360 seconds, or only a 3% performance hit.

If you can deal with sometimes working with floats and sometimes Fractions, this may be the way to go.

鹿港小镇 2025-01-02 14:20:28

我什么也没找到。
你可以制作一个。http://docs.python.org/extending/extending.html

快速搜索 c 中的分数给了我 http://www.spiration.co.uk/post/1400/fractions-in-c---a-rational-arithmetic-library。使用第二篇文章,它也处理负数。

但这可能不是您需要的,您可以找到其他东西。如果你不想扩展 python,并且找不到任何拥有 cFractions 模块的人,则必须坚持使用 Fractions。对不起。

I couldn't find anything.
You could make one.http://docs.python.org/extending/extending.html

A quick search on fractions in c gave me http://www.spiration.co.uk/post/1400/fractions-in-c---a-rational-arithmetic-library. Use the 2nd post, it also handles negative numbers.

But that may not be what you need and you can find something else. If you don't want to extend python you have to stick to Fractions if you can't find anyone who has a cFractions module. I'm sorry.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文