Почему код Python работает быстрее в функции?

В дополнение к M. Собственный простой и прагматичный ответ Дадли Более сжатая переформулировка ForNeVeR ):

Для удобства здесь представлена ​​расширенная функция Out-FileUtf8NoBom, альтернатива на основе трубопровода, которая имитирует Out-File, что означает:

  • вы можете использовать его так же, как Out-File в конвейере.
  • входные объекты, которые не являются строками, отформатированы так, как если бы они были, если вы отправили их на консоль, как с Out-File.

Пример:

(Get-Content $MyPath) | Out-FileUtf8NoBom $MyPath

Обратите внимание, что (Get-Content $MyPath) заключен в (...), который гарантирует, что весь файл будет открыт, прочитан полностью и закрыт перед отправкой результата по конвейеру. Это необходимо, чтобы иметь возможность записать обратно в тот же файл (обновите его на месте ). Как правило, этот метод не рекомендуется по двум причинам: (a) весь файл должен вписываться в память и (b) если команда прервана, данные будут потеряны.

Примечание об использовании памяти :

  • M. Собственный ответ Дадли требует, чтобы сначала было записано все содержимое файла в памяти, что может быть проблематичным для больших файлов.
  • Функция ниже улучшается только при этом: все входные объекты по-прежнему буферизуются во-первых, но их строковые представления затем сгенерированы и записываются в выходной файл один за другим.

Исходный код Out-FileUtf8NoBom (также доступен как лицензированный MIT Gist ):

<#
.SYNOPSIS
  Outputs to a UTF-8-encoded file *without a BOM* (byte-order mark).

.DESCRIPTION
  Mimics the most important aspects of Out-File:
  * Input objects are sent to Out-String first.
  * -Append allows you to append to an existing file, -NoClobber prevents
    overwriting of an existing file.
  * -Width allows you to specify the line width for the text representations
     of input objects that aren't strings.
  However, it is not a complete implementation of all Out-String parameters:
  * Only a literal output path is supported, and only as a parameter.
  * -Force is not supported.

  Caveat: *All* pipeline input is buffered before writing output starts,
          but the string representations are generated and written to the target
          file one by one.

.NOTES
  The raison d'être for this advanced function is that, as of PowerShell v5,
  Out-File still lacks the ability to write UTF-8 files without a BOM:
  using -Encoding UTF8 invariably prepends a BOM.

#>
function Out-FileUtf8NoBom {

  [CmdletBinding()]
  param(
    [Parameter(Mandatory, Position=0)] [string] $LiteralPath,
    [switch] $Append,
    [switch] $NoClobber,
    [AllowNull()] [int] $Width,
    [Parameter(ValueFromPipeline)] $InputObject
  )

  #requires -version 3

  # Make sure that the .NET framework sees the same working dir. as PS
  # and resolve the input path to a full path.
  [System.IO.Directory]::SetCurrentDirectory($PWD) # Caveat: .NET Core doesn't support [Environment]::CurrentDirectory
  $LiteralPath = [IO.Path]::GetFullPath($LiteralPath)

  # If -NoClobber was specified, throw an exception if the target file already
  # exists.
  if ($NoClobber -and (Test-Path $LiteralPath)) {
    Throw [IO.IOException] "The file '$LiteralPath' already exists."
  }

  # Create a StreamWriter object.
  # Note that we take advantage of the fact that the StreamWriter class by default:
  # - uses UTF-8 encoding
  # - without a BOM.
  $sw = New-Object IO.StreamWriter $LiteralPath, $Append

  $htOutStringArgs = @{}
  if ($Width) {
    $htOutStringArgs += @{ Width = $Width }
  }

  # Note: By not using begin / process / end blocks, we're effectively running
  #       in the end block, which means that all pipeline input has already
  #       been collected in automatic variable $Input.
  #       We must use this approach, because using | Out-String individually
  #       in each iteration of a process block would format each input object
  #       with an indvidual header.
  try {
    $Input | Out-String -Stream @htOutStringArgs | % { $sw.WriteLine($_) }
  } finally {
    $sw.Dispose()
  }

}

795
задан thedoctar 31 October 2016 в 02:07
поделиться