调用自定义函数很慢

尼古拉斯·斯特凡纽克

我有一个关于 powershell (v4) 的新手问题。

鉴于以下代码,

  • 当我在循环中执行 $t = $i 时,它需要 0.5 秒
  • 当我在循环中执行 $t = DoNothing($i) 时需要 11.5 秒
  • 当我在循环中执行 $t = DoNothing $i 时需要 11.5 秒

如果我更改函数 DoNothing 的内容来做某事,时间不会延长太多。

显然我在某个地方犯了一个大错误,但我看不到它在哪里。非常感谢帮助我理解我的错误。

    function DoNothing($val) 
{
    return $val
}

Write-Host "Script started..."
$elapsed = [System.Diagnostics.Stopwatch]::StartNew() 


for($i=1
     $i -le 100000
     $i++){
     #$t = $i
     #$t = DoNothing($i)
     $t = DoNothing $i
     }

Write-Host "Script complete."
Write-Host "Total Elapsed Time: $($elapsed.Elapsed.ToString())"
詹姆士

好问题。我相信这只是在 PowerShell 中进行函数调用的性能开销,但我做了一些实验来检查。

我注意到的一些事情:

1)与仅使用 PowerShell ISE 而不保存文件相比,保存文件提高了约 75% 的性能(从 7.3 秒到 4.3 秒)。

2)转到DoNothing通过附加〜25%转化为无参数的功能得到改善的执行时间(从4.3秒至3.3秒)。如果创建$i为全局变量可以节省时间,这将很有用,但我也测试了这一点,遗憾的是,它将执行时间增加到 4.7 秒。

3)我认为可能明确要求$val作为 int 传入会减少执行时间,但事实并非如此。时间增加了约0.2秒。

4)-val在调用DoNothing( $t = DoNothing -val $i)命名参数并没有提高性能。

5)使用$val而不是return $val没有提高性能。

6)使用-lt而不是-le没有提高性能。

7)添加DoNothing到只有其中DoNothing功能的 PS 模块会严重降低性能(从 4.3 秒到 15 秒)。

所以,我认为这都是由于功能开销造成的。我在您的代码中没有看到任何“错误”。

这是一个有趣的实验,当我将来选择使用 PowerShell 函数时可能会改变。我想知道这与其他脚本语言相比如何。

出于好奇,我使用 C# 运行了这些相同的操作,整个过程在千分之一秒内完成。代码如下。

class Program
{
    private static int DoNothing(int val) {
        return val;
    }
    static void Main(string[] args)
    {
        System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();
        for (int i = 1; i <= 100000; i++)
        {
            int t = DoNothing(i);
        }
        Console.WriteLine(watch.Elapsed.ToString());
        Console.ReadKey();
    }
}

现在我已经比这更进一步了。我想如果您真的需要它更快,也许您可​​以将工作负载从 PowerShell 转移到 C#。这最终比 PowerShell 中的初始实现快得多,但比 C# only 选项慢。此代码运行约 0.03 秒。请参阅下面的代码。

PowerShell(调用 C#)

$elapsed = [System.Diagnostics.Stopwatch]::StartNew()
Write-Host "Script started..."
$lib = [Reflection.Assembly]::LoadFile("C:\Users\you\source\ClassLibrary1\bin\Debug\ClassLibrary1.dll")
$type = $lib.GetType("ClassLibrary1.Class1")
$method = $type.GetMethod("MyFunction")
$o = [Activator]::CreateInstance($type)
$method.Invoke($o, $null)
Write-Host "Script complete."
Write-Host "Total Elapsed Time: $($elapsed.Elapsed.ToString())"

C#(做工作)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public class Class1
    {
        public static int DoNothing(int val)
        {
            return val;
        }

        public static void MyFunction()
        {
            for (int i = 1; i <= 100000; i++)
            {
                int t = DoNothing(i);
            }
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

定义和调用自定义函数

来自分类Dev

在简码中调用自定义函数

来自分类Dev

从Java调用自定义R函数

来自分类Dev

从Java调用自定义R函数

来自分类Dev

调用显示表单的自定义函数

来自分类Dev

在dplyr中使用{{}}调用自定义函数

来自分类Dev

具有自定义函数调用的HTML表单

来自分类Dev

在点击时从自定义指令调用函数吗?-AngularJS

来自分类Dev

创建自定义构造函数而不直接调用继承

来自分类Dev

如何从自定义基本适配器调用函数

来自分类Dev

从外部网址调用自定义GAS函数

来自分类Dev

自定义TextView-setText()在构造函数之前调用

来自分类Dev

自定义视图构造函数未调用

来自分类Dev

Swift:自定义类的函数调用引发异常

来自分类Dev

角度自定义指令调用内联函数

来自分类Dev

python从bash外壳调用自定义函数

来自分类Dev

在自定义容器中调用析构函数

来自分类Dev

树枝:创建调用函数的自定义标签

来自分类Dev

从js.haml调用自定义javascript函数

来自分类Dev

使用IEqualityComparer时未调用自定义Equals函数

来自分类Dev

如何从自定义基本适配器调用函数

来自分类Dev

如何调用此自定义jquery函数

来自分类Dev

调用了自定义UITableViewCell函数,但显示了本机表

来自分类Dev

Drupal 7模块自定义JavaScript AJAX函数调用

来自分类Dev

从带有参数的自定义文件中调用函数

来自分类Dev

具有自定义函数调用的HTML表单

来自分类Dev

通过网址在joomla插件中调用自定义函数。

来自分类Dev

在自定义容器中调用析构函数

来自分类Dev

Vim:在自定义函数中调用对象方法