C# PowerShell脚本效率

C# PowerShell脚本效率,c#,performance,powershell,C#,Performance,Powershell,我尽可能多地使用PowerShell来完成快速简单的脚本任务;在我的工作中,很多时候我会使用它进行数据解析、日志文件筛选或创建CSV\Text文件 有一件事我不明白,为什么执行某些data\IO任务会非常低效。我想这与引擎盖下的某些东西,以及它处理管道的方式有关,或者只是一些我还不了解的东西 如果采用以下逻辑生成ABC123 ID,在PowerShell中编译并执行它,则不到1分钟即可完成: $source = @' public static System.Collections.Ge

我尽可能多地使用PowerShell来完成快速简单的脚本任务;在我的工作中,很多时候我会使用它进行数据解析、日志文件筛选或创建CSV\Text文件

有一件事我不明白,为什么执行某些data\IO任务会非常低效。我想这与引擎盖下的某些东西,以及它处理管道的方式有关,或者只是一些我还不了解的东西

如果采用以下逻辑生成ABC123 ID,在PowerShell中编译并执行它,则不到1分钟即可完成:

$source = @'
    public static System.Collections.Generic.List<String> GetIds()
    {
        System.Collections.Generic.List<String> retValue = new System.Collections.Generic.List<String>();
        for (int left = 97; left < 123; left++)
        {
            for (int middle = 97; middle < 123; middle++)
            {
                for (int right = 97; right < 123; right++)
                {
                    for (int i = 1; i < 1000; i++)
                    {
                        String tmp = String.Format("{0}{1}{2}000", (char)left, (char)middle, (char)right);
                        retValue.Add(String.Format("{0}{1}", tmp.Substring(0, tmp.Length - i.ToString().Length), i));
                    }
                }
            }
        }
        return retValue;
    }
'@
$util = Add-Type -Name "Utils" -MemberDefinition $source -PassThru -Language CSharp

$start = get-date
$ret = $util::GetIds()
Write-Host ("Time: {0} minutes" -f ((get-date)-$start).TotalMinutes)

为什么呢?是否有某种类型的过度类型转换或效率低下的操作会降低性能?

您正在扼杀您的性能:

$retValue += ("{0}{1}" -f $tmp.Substring(0, $tmp.Length - $i.ToString().Length), $i)
阵列添加是一项非常“昂贵”的操作。您所做的基本上是每次创建一个全新的数组,由原始数组和新元素组成

编辑:这种数组添加不仅效率低下,而且完全没有必要。您只需将这些值输出到管道,并将结果赋回变量即可

$start = Get-Date
$retValue =
for ($left = 97; $left -lt 123; $left++)
{ 
    for ($middle = 97; $middle -lt 123; $middle++)
    { 
        for ($right = 97; $right -lt 123; $right++)
        { 
            for ($i = 1; $i -lt 1000; $i++)
            { 
                $tmp = ("{0}{1}{2}000" -f [char]$left, [char]$middle, [char]$right)
                "{0}{1}" -f $tmp.Substring(0, $tmp.Length - $i.ToString().Length), $i
            }
        }
    }
}
Write-Host ("Time: {0} minutes" -f ((get-date)-$start).TotalMinutes)
Time: 1.866812045 minutes

很不错的!现在很有道理了。我假设
System.Collections.Generic.List
@()
的类型不同。System.Collections.Generic.List.Add方法是否执行数组扩展?再次感谢!泛型列表的.add()方法比数组加法更有效。arralist类型在有效添加元素方面似乎是最快的,但通常情况下,您只需要在管道已用于其他对象的情况下执行此操作,并且需要在管道之外执行偶然累积。
$start = Get-Date
$retValue =
for ($left = 97; $left -lt 123; $left++)
{ 
    for ($middle = 97; $middle -lt 123; $middle++)
    { 
        for ($right = 97; $right -lt 123; $right++)
        { 
            for ($i = 1; $i -lt 1000; $i++)
            { 
                $tmp = ("{0}{1}{2}000" -f [char]$left, [char]$middle, [char]$right)
                "{0}{1}" -f $tmp.Substring(0, $tmp.Length - $i.ToString().Length), $i
            }
        }
    }
}
Write-Host ("Time: {0} minutes" -f ((get-date)-$start).TotalMinutes)
Time: 1.866812045 minutes