是否有可能在Perl中有条件地“使用bigint”?

时间:2021-05-23 16:51:54

I know I can conditionally use a module in Perl but what about the "pragmas"? My tests have shown that use bigint can be much slower than normal math in Perl and I only need it to handle 64-bit integers so I only want to use it when Perl wasn't built with 64-bit integer support, which I also know how to check for using the Config module.

我知道我可以在Perl中有条件地使用模块但是“pragma”呢?我的测试表明使用bigint比Perl中的普通数学慢得多,我只需要它来处理64位整数,所以我只想在Perl没有用64位整数支持构建时使用它,我也是知道如何检查使用Config模块。

I tried various things with eval and BEGIN blocks but couldn't work out a way to conditionally use bigint. I know I can use Math::BigInt but then I can't use a single codepath for both the bigint and 64-bit cases.

我用eval和BEGIN块尝试了各种各样的东西,但无法有条件地使用bigint。我知道我可以使用Math :: BigInt但是我不能为bigint和64位情况使用单个代码路径。

3 个解决方案

#1


15  

This actually works just fine:

这实际上工作得很好:

use Config;
BEGIN {
  if (! $Config{use64bitint}) {
    require bigint;
    bigint->import;
  }
}

The interaction between different compile-times is complicated (maybe I'll come back and try to explain it later) but suffice it to say that since there's no string eval here, the flag that bigint sets will persist through the rest of the file or block that you put that BEGIN block inside.

不同编译时间之间的交互是复杂的(也许我会回来并尝试稍后解释)但是足以说明,因为这里没有字符串eval,bigint设置的标志将持续通过文件的其余部分或阻止您将BEGIN块放入其中。

#2


13  

You can take hobbs' answer and stick it in a module.

你可以把霍布斯的答案拿到一个模块中。

package int64;

use Config;

sub import {
    if (! $Config{use64bitint}) {
        require bigint;
        bigint->import;
    }
}

1;

Then use int64 will do what you mean. Even though bigint is lexical, calling it inside another import routine will make it pass along its magic.

那么使用int64会做你的意思。尽管bigint是词法,但在另一个导入例程中调用它会使它传递它的魔力。

#3


12  

Use the if module. It uses goto to hide its own stack frame, so it's as if the pragma was called directly.

使用if模块。它使用goto隐藏自己的堆栈帧,因此就好像直接调用了pragma一样。

The solutions given previously may work for bigint and most pragmas, but they will fail for import functions that use caller.

之前给出的解决方案可能适用于bigint和大多数编译指示,但对于使用调用方的导入函数,它们将失败。

#1


15  

This actually works just fine:

这实际上工作得很好:

use Config;
BEGIN {
  if (! $Config{use64bitint}) {
    require bigint;
    bigint->import;
  }
}

The interaction between different compile-times is complicated (maybe I'll come back and try to explain it later) but suffice it to say that since there's no string eval here, the flag that bigint sets will persist through the rest of the file or block that you put that BEGIN block inside.

不同编译时间之间的交互是复杂的(也许我会回来并尝试稍后解释)但是足以说明,因为这里没有字符串eval,bigint设置的标志将持续通过文件的其余部分或阻止您将BEGIN块放入其中。

#2


13  

You can take hobbs' answer and stick it in a module.

你可以把霍布斯的答案拿到一个模块中。

package int64;

use Config;

sub import {
    if (! $Config{use64bitint}) {
        require bigint;
        bigint->import;
    }
}

1;

Then use int64 will do what you mean. Even though bigint is lexical, calling it inside another import routine will make it pass along its magic.

那么使用int64会做你的意思。尽管bigint是词法,但在另一个导入例程中调用它会使它传递它的魔力。

#3


12  

Use the if module. It uses goto to hide its own stack frame, so it's as if the pragma was called directly.

使用if模块。它使用goto隐藏自己的堆栈帧,因此就好像直接调用了pragma一样。

The solutions given previously may work for bigint and most pragmas, but they will fail for import functions that use caller.

之前给出的解决方案可能适用于bigint和大多数编译指示,但对于使用调用方的导入函数,它们将失败。