From a281d3d971e8a89bb6b52043c62fef6e12c2d2f7 Mon Sep 17 00:00:00 2001 From: Jason Shirk Date: Sun, 14 Jul 2019 14:49:45 -0700 Subject: [PATCH] Faster pipeline binding for ForEach-Object --- .../engine/CommandDiscovery.cs | 13 +++++--- .../engine/CommandProcessor.cs | 31 ++++++++++++++++++- .../engine/CommandProcessorBase.cs | 7 ----- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/System.Management.Automation/engine/CommandDiscovery.cs b/src/System.Management.Automation/engine/CommandDiscovery.cs index d5c639430cf..4fb8345e142 100644 --- a/src/System.Management.Automation/engine/CommandDiscovery.cs +++ b/src/System.Management.Automation/engine/CommandDiscovery.cs @@ -529,9 +529,6 @@ private static string BuildPSSnapInDisplayName(PSSnapInSpecification PSSnapin) /// The session state the commandInfo should be run in. /// /// - /// - /// If the command, , could not be found. - /// /// /// If the security manager is preventing the command from running. /// @@ -575,7 +572,15 @@ internal CommandProcessorBase LookupCommandProcessor(CommandInfo commandInfo, processor = new NativeCommandProcessor((ApplicationInfo)commandInfo, Context); break; case CommandTypes.Cmdlet: - processor = new CommandProcessor((CmdletInfo)commandInfo, Context); + var cmdletInfo = (CmdletInfo)commandInfo; + if (cmdletInfo.ImplementingType == typeof(ForEachObjectCommand)) + { + processor = new SimpleForEachObjectCommandProcessor(cmdletInfo, Context); + } + else + { + processor = new CommandProcessor(cmdletInfo, Context); + } break; case CommandTypes.ExternalScript: ExternalScriptInfo scriptInfo = (ExternalScriptInfo)commandInfo; diff --git a/src/System.Management.Automation/engine/CommandProcessor.cs b/src/System.Management.Automation/engine/CommandProcessor.cs index 40fb3eff83f..203f32bcda7 100644 --- a/src/System.Management.Automation/engine/CommandProcessor.cs +++ b/src/System.Management.Automation/engine/CommandProcessor.cs @@ -83,6 +83,16 @@ internal CommandProcessor(IScriptCommandInfo scriptCommandInfo, ExecutionContext Init(scriptCommandInfo); } + protected CommandProcessor(CmdletInfo cmdletInfo, ExecutionContext context, ForEachObjectCommand instance) + : base(cmdletInfo) + { + this._context = context; + this.Command = instance; + this.CommandScope = Context.EngineSessionState.CurrentScope; + + InitCommon(); + } + #endregion ctor #region internal members @@ -663,7 +673,12 @@ private bool ProcessInputPipelineObject(object inputObject) Command.CurrentPipelineObject = inputToOperateOn; - return this.CmdletParameterBinderController.BindPipelineParameters(inputToOperateOn); + return this.BindPipelineParameters(inputToOperateOn); + } + + protected virtual bool BindPipelineParameters(PSObject inputObject) + { + return this.CmdletParameterBinderController.BindPipelineParameters(inputObject); } private static readonly ConcurrentDictionary> s_constructInstanceCache; @@ -868,5 +883,19 @@ internal override bool IsHelpRequested(out string helpTarget, out HelpCategory h #endregion helper_methods } + + internal class SimpleForEachObjectCommandProcessor : CommandProcessor + { + internal SimpleForEachObjectCommandProcessor(CmdletInfo cmdletInfo, ExecutionContext context) + : base(cmdletInfo, context, new ForEachObjectCommand()) + { + } + + protected override bool BindPipelineParameters(PSObject inputObject) + { + ((ForEachObjectCommand)this.Command).InputObject = inputObject; + return true; + } + } } diff --git a/src/System.Management.Automation/engine/CommandProcessorBase.cs b/src/System.Management.Automation/engine/CommandProcessorBase.cs index 042a69489ca..38bb37ed86c 100644 --- a/src/System.Management.Automation/engine/CommandProcessorBase.cs +++ b/src/System.Management.Automation/engine/CommandProcessorBase.cs @@ -18,13 +18,6 @@ internal abstract class CommandProcessorBase : IDisposable { #region ctor - /// - /// Default constructor. - /// - internal CommandProcessorBase() - { - } - /// /// Initializes the base command processor class with the command metadata. ///