我有一个关于 powershell (v4) 的新手问题。
鉴于以下代码,
如果我更改函数 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] 删除。
我来说两句