调用子程序的最快方法 [英] Fastest way of calling a subroutine

查看:119
本文介绍了调用子程序的最快方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,在Perl中,我们可以使用以下技术从模块调用子例程:

As far as I know, in Perl, we can call a subroutine from a Module by using these techniques:

  • 导出子程序foo,导入具有该子程序的模块.最后,在您的perl脚本中调用它.
  • 在您的perl脚本中创建该模块的Object,最后使用该Object调用foo.
  • 使用其路径直接调用foo,例如myDir::Module::foo();.
  • Export subroutine foo, import the module which has this subroutine. Finally call it in your perl script.
  • Create an Object of that Module in your perl script finally call foo using that Object.
  • Directly call foo using its path, like this myDir::Module::foo();.

如果我总是很困惑,那是调用子例程foo的更好方法. 如果我有一个动态脚本,该脚本是从浏览器而不是命令行运行的,则应该采用这种方法,以便脚本花费的时间更少.

If I am always confused which is better way of calling a subroutine foo. If I have a dynamic script, which I run from the browser and not command line, which approach one should go for so that the script takes less time.

谢谢.

推荐答案

在Perl中调用代码的最快方法和最佳方法之间是有区别的.

There is a difference between the fastest, and the best way to call code in Perl.

也请参见simbabques答案.他特别介绍了#1和#3之间的区别,以及为什么要使用两者之一.

please see simbabques answer as well. He especially covers the differences between #1 and #3, and why you would use either.

您的#1和#3相同:子例程在全局可见的命名空间中具有唯一的名称.许多名称可能通过别名或导入模块映射到一个子例程.

Your #1 and #3 are identical: The subroutine has an unique name in the globally visible namespace. Many names may map to one subroutine via aliases, or importing a module.

如果在编译时知道您正在调用的函数的名称,则将在编译时解析该子项.假设您没有自发地重新定义函数.如果仅在运行时才知道确切的函数,则只需进行哈希查找即可.

If the name of the function you are calling is known at compile time, the sub will be resolved at compile time. This assumes that you don't spontaneously redefine your functions. If the exact function is only known at runtime, this is only a hash lookup away.

可以通过三种方式调用函数:

There are three ways how functions can be called:

foo(@args);
&foo(@args);
@_ = @args; goto &foo;

默认为第一(括号有时是可选的),并针对子原型验证您的参数(不要使用原型).同样,构造了整个调用堆栈框架(包含许多有用的调试信息).这需要时间.

Number one (braces sometimes optional) is default, and validates your arguments against the sub prototype (don't use prototypes). Also, a whole call stack frame (with much useful debug information) is constructed. This takes time.

第二个跳过原型验证,并假设您知道自己在做什么.这稍微快一点.我认为这是草率的风格.

Number two skips the protoype verification, and assumes that you know what you are doing. This is slightly faster. I think this is sloppy style.

第三个是尾声.它从当前子站返回,返回值为foo.这是快速的,因为忽略了原型,并且可以重用当前的调用堆栈框架.这通常用处不大,语法也很丑陋.内联代码大约快一个数量级(即在Perl中,我们更喜欢循环而不是递归☹).

Number three is a tail call. This returns from the current sub with the return value of foo. This is fast, as prototypes are ignored, and the current call stack frame can be reused. This isn't useful very often, and has ugly syntax. Inlining the code is about an order of magnitude faster (i.e. in Perl, we prefer loops over recursion ☹).

OO的灵活性要付出巨大的性能代价:由于直到运行时才知道调用消息的对象的类型,因此只能在运行时解析实际的方法.

The flexibility of OO comes at a hefty performance price: As the type of the object you call the message on is never known until runtime, the actual method can only be resolved at runtime.

这意味着$foo->bar()$foo被放入的包中查找函数bar.如果在该处找不到,它将在父类中进行搜索.太慢了如果要使用OO,请注意浅层次结构(→较少的查找).还应注意,Perls默认的方法解析顺序是不寻常的.

This means that $foo->bar() looks up the function bar in the package that $foo was blessed into. If it can't be found there, it will be searched for in parent classes. This is slow. If you want to use OO, pay attention to shallow hierarchies (→ less lookups). Do also note that Perls default Method Resolution Order is unusual.

即使知道类型,通常也无法将方法调用减少为函数调用.

You cannot generally reduce a method call to a function call, even if you know the type.

如果$foo如果Foo类是Foo::bar的子类,则Foo::bar($foo)将跳过方法结果,甚至可能起作用.但是,这会破坏封装,一旦Foo被子类化,它将破坏.另外,如果Foo没有定义bar,但是该方法是在父类中定义的,则此方法无效.

If $foo if of class Foo, and Foo::bar is a sub, then Foo::bar($foo) will skip the method resultution, and might even work. However, this breaks encapsulation, and will break once Foo is subclassed. Also, this doesn't work if Foo doesn't define bar, but the method was defined in a parent class.

在基准测试明确表明这不能提供您所需的性能之前,我一般都倾向于面向对象.

I am generally in favour of object orientation, until it is clear from benchmarks that this will not provide the performance you require.

这篇关于调用子程序的最快方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆