我可以让这个脚本更快吗? [英] Can I make this script even faster?

查看:57
本文介绍了我可以让这个脚本更快吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为实习编写了一个简单的脚本,它遍历提供的目录并删除任何早于指定天数的文件.我今天所有的空闲时间都在试图收紧它.这是我到目前为止所得到的:

I wrote a simple script for an internship, which trawls through a provided directory and deletes any file older than a specified number of days. I've spent all my free time today attempting to tighten it up. Here's what I've got so far:

function delOld($dir, $numDays){
    $timespan = new-timespan -days $numDays
    $curTime = get-date
    get-childItem $dir -Recurse -file | 
    where-object {(($curTime)-($_.LastWriteTime)) -gt $timespan} | 
    remove-Item -whatif
}

这是一个函数调用的例子:

Here is an example of a call of the function:

delOld -dir "C:\Users\me\Desktop\psproject" -numDays 5

抱歉阅读困难,我发现将操作压缩为一行比每次迭代将它们重新分配给清晰的变量更有效.出于测试目的,删除项目目前是 whatif'd.我知道在这一点上,我可能无法加快速度,但是,我在 TB 的文件上运行它,所以每个操作都很重要.

Sorry for the difficulty of reading, I found that condensing the operations into one line was more efficient than reassigning them to legible variables each iteration. The remove-item is whatif'd at the moment for testing purposes. I'm aware that at this point, I probably cannot speed it up much, however, I am running it on over a TB of files, so every operation counts.

预先感谢您提供的任何建议!

Thanks in advance for any advice you have to offer!

推荐答案

停留在 PowerShell 和 .NET 方法领域,您可以通过以下方式加快函数速度:

Staying in the realm of PowerShell and .NET methods, here's how you can speed up your function:

  • 预先计算截止时间戳一次.

[IO.DirectoryInfo] 类型的 EnumerateFiles() 方法 (PSv3+/.NET4+) 与 foreach 结合使用声明.wOxxOm.

Use the [IO.DirectoryInfo] type's EnumerateFiles() method (PSv3+ / .NET4+) in combination with a foreach statement. Tip of the hat to wOxxOm.

  • EnumerateFiles() 一次枚举一个文件,保持内存使用不变,类似于 Get-ChildItem,但速度更快.

  • EnumerateFiles() enumerates files one at a time, keeping memory use constant, similar to, but faster than Get-ChildItem.

  • 注意事项:

  • EnumerateFiles() 总是包括隐藏文件,而Get-ChildItem默认排除它们, 并且仅在指定了 -Force 时才包括它们.

  • EnumerateFiles() invariably includes hidden files, whereas Get-ChildItem excludes them by default, and only includes them if -Force is specified.

EnumerateFiles() 如果由于缺乏权限而有可能遇到无法访问的目录,则不适合,因为即使您将整个 foreach 括起来 语句在 try/catch 块中,你只会得到 部分 输出,因为迭代停止 遇到第一个无法访问的目录.

EnumerateFiles() is unsuitable if there's a chance of encountering inaccessible directories due to lack of permissions, because even if you enclose the entire foreach statement in a try / catch block, you'll only get partial output, given that the iteration stops on encountering the first inaccessible directory.

枚举顺序可以与 Get-ChildItem 的不同.

The enumeration order can differ from that of Get-ChildItem.

PowerShell 的 foreach statementForEach-Object cmdlet 快得多,而且速度也更快比 PSv4+ .ForEach() 集合方法.

PowerShell's foreach statement is much faster than the ForEach-Object cmdlet, and also faster than the PSv4+ .ForEach() collection method.

直接在循环体内的每个 [System.IO.FileInfo] 实例上调用 .Delete() 方法.

Invoke the .Delete() method directly on each [System.IO.FileInfo] instance inside the loop body.

注意:为简洁起见,下面的函数中没有错误检查,例如$numDays是否有允许的值以及$dir是否引用到现有目录(如果它是基于自定义 PS 驱动器的路径,则必须首先使用 Convert-Path 解析它).

Note: For brevity, there are no error checks in the function below, such as for whether $numDays has a permissible value and whether $dir refers to an existing directory (if it's a path based on a custom PS drive, you'd have to resolve it with Convert-Path first).

function delOld($dir, $numDays) {
    $dtCutoff = [datetime]::now - [timespan]::FromDays($numDays)
    # Make sure that the .NET framework's current dir. is the same as PS's:
    [System.IO.Directory]::SetCurrentDirectory($PWD.ProviderPath)
    # Enumerate all files recursively.
    # Replace $file.FullName with $file.Delete() to perform actual deletion.
    foreach ($file in ([IO.DirectoryInfo] $dir).EnumerateFiles('*', 'AllDirectories')) { 
     if ($file.LastWriteTime -lt $dtCutOff) { $file.FullName }
    }
}

注意:上面只是输出要删除的文件的路径;将 $file.FullName 替换为 $file.Delete() 以执行实际删除.

Note: The above simply outputs the paths of the files to delete; replace $file.FullName with $file.Delete() to perform actual deletion.

这篇关于我可以让这个脚本更快吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆