gpt4 book ai didi

powershell - 调用自定义函数非常慢

转载 作者:行者123 更新时间:2023-12-05 03:06:31 24 4
gpt4 key购买 nike

我有一个关于 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) 在调用 DoNothing 时命名 -val 参数 ($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# 选项慢。 此代码运行时间约为 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);
}
}
}
}

关于powershell - 调用自定义函数非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49199261/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com