c# - PowerShell 脚本效率

标签 c# performance powershell

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

有一件事我不明白,为什么执行某些数据\IO 任务会非常低效。我认为它与处理管道的方式有关,或者只是我还不了解的事情。

如果采用以下逻辑生成ABC123 ids,在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)

现在采用相同的逻辑,通过 PowerShell 运行它而不编译为程序集,它需要数小时才能完成

$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)
                $retValue += ("{0}{1}" -f $tmp.Substring(0, $tmp.Length - $i.ToString().Length), $i)
            }
        }
    }
}
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

关于c# - PowerShell 脚本效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28884718/

相关文章:

c# - 如何基于多个xml属性存储和查找数据?

javascript - 就性能而言,缩小/编译的 JavaScript 与未压缩的 JavaScript

powershell - 卸载以特定字符串开头的所有软件

c# - 跟踪消息未出现在 trace.axd 中

c# - WinForms DataGridView - 更新数据库

performance - 在 Kubernetes 中并置 pod

python - Graph API 以编程方式验证用户身份

powershell - 术语 'Get-WebBinding' 未被识别为 cmdlet、函数、脚本文件或可操作程序的名称

c# - 使用关键字 new 将委托(delegate)添加到事件中是否安全?

node.js - 使用 Stylus 和 CoffeeScript 中间件是否会降低 Node.js Express 应用程序的速度?