public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Kinney, Michael D" <michael.d.kinney@intel.com>
To: "Gao, Liming" <liming.gao@intel.com>,
	"Feng, Bob C" <bob.c.feng@intel.com>,
	"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>
Cc: "Carsey, Jaben" <jaben.carsey@intel.com>
Subject: Re: [Patch] BaseTools: Optimize string concatenation
Date: Fri, 9 Nov 2018 17:01:22 +0000	[thread overview]
Message-ID: <E92EE9817A31E24EB0585FDF735412F5B8B2DA93@ORSMSX113.amr.corp.intel.com> (raw)
In-Reply-To: <4A89E2EF3DFEDB4C8BFDE51014F606A14E368206@SHSMSX104.ccr.corp.intel.com>

Liming,

If we can support both Python2 and Python3 equally,
then I agree that these types of performance enhancements
can be added to edk2/master after the stable tag.

Let's make sure we enter a BZ for each performance
improvement and as Leif has asked, put evidence of the
performance improvement in the BZ.

Mike

> -----Original Message-----
> From: Gao, Liming
> Sent: Friday, November 9, 2018 6:17 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>;
> Feng, Bob C <bob.c.feng@intel.com>; edk2-
> devel@lists.01.org
> Cc: Carsey, Jaben <jaben.carsey@intel.com>
> Subject: RE: [edk2] [Patch] BaseTools: Optimize string
> concatenation
> 
> Mike:
>   This patch bases on edk2 master with Python27.
> Seemly, most people are not aware that Python3
> migration
> (https://bugzilla.tianocore.org/show_bug.cgi?id=55) is
> added for next edk2-stable201903 tag planning. In BZ
> 55, I propose to keep Python2 and Python3 both, and new
> feature and patches are created based on Python3. I
> will send the mail to collect the feedback on this
> approach.
> 
> Thanks
> Liming
> > -----Original Message-----
> > From: Kinney, Michael D
> > Sent: Friday, November 9, 2018 12:41 AM
> > To: Feng, Bob C <bob.c.feng@intel.com>; edk2-
> devel@lists.01.org; Kinney, Michael D
> <michael.d.kinney@intel.com>
> > Cc: Carsey, Jaben <jaben.carsey@intel.com>; Gao,
> Liming <liming.gao@intel.com>
> > Subject: RE: [edk2] [Patch] BaseTools: Optimize
> string concatenation
> >
> > Bob,
> >
> > Is this for edk2/master or for the Python 3
> conversion in the
> > edk2-staging branch?  If it is for the edk-staging
> branch, then
> > the Subject is not correct.
> >
> > Thanks,
> >
> > Mike
> >
> > > -----Original Message-----
> > > From: edk2-devel [mailto:edk2-devel-
> > > bounces@lists.01.org] On Behalf Of BobCF
> > > Sent: Thursday, November 8, 2018 2:16 AM
> > > To: edk2-devel@lists.01.org
> > > Cc: Carsey, Jaben <jaben.carsey@intel.com>; Gao,
> Liming
> > > <liming.gao@intel.com>
> > > Subject: [edk2] [Patch] BaseTools: Optimize string
> > > concatenation
> > >
> > > https://bugzilla.tianocore.org/show_bug.cgi?id=1288
> > >
> > > This patch is one of build tool performance
> improvement
> > > series patches.
> > >
> > > This patch is going to use join function instead of
> > > string += string2 statement.
> > >
> > > Current code use string += string2 in a loop to
> combine
> > > a string. while creating a string list in a loop
> and
> > > using
> > > "".join(stringlist) after the loop will be much
> faster.
> > >
> > > Contributed-under: TianoCore Contribution Agreement
> 1.1
> > > Signed-off-by: BobCF <bob.c.feng@intel.com>
> > > Cc: Liming Gao <liming.gao@intel.com>
> > > Cc: Jaben Carsey <jaben.carsey@intel.com>
> > > ---
> > >  BaseTools/Source/Python/AutoGen/StrGather.py  | 39
> > > +++++++++++++------
> > >  BaseTools/Source/Python/Common/Misc.py        | 21
> > > +++++-----
> > >  .../Source/Python/Workspace/InfBuildData.py   |  4
> +-
> > >  .../Python/Workspace/WorkspaceCommon.py       | 11
> ++-
> > > ---
> > >  4 files changed, 44 insertions(+), 31 deletions(-)
> > >
> > > diff --git
> > > a/BaseTools/Source/Python/AutoGen/StrGather.py
> > > b/BaseTools/Source/Python/AutoGen/StrGather.py
> > > index 361d499076..d34a9e9447 100644
> > > --- a/BaseTools/Source/Python/AutoGen/StrGather.py
> > > +++ b/BaseTools/Source/Python/AutoGen/StrGather.py
> > > @@ -135,11 +135,11 @@ def AscToHexList(Ascii):
> > >  # @param UniGenCFlag      UniString is generated
> into
> > > AutoGen C file when it is set to True
> > >  #
> > >  # @retval Str:           A string of .h file
> content
> > >  #
> > >  def CreateHFileContent(BaseName, UniObjectClass,
> > > IsCompatibleMode, UniGenCFlag):
> > > -    Str = ''
> > > +    Str = []
> > >      ValueStartPtr = 60
> > >      Line = COMMENT_DEFINE_STR + ' ' +
> > > LANGUAGE_NAME_STRING_NAME + ' ' * (ValueStartPtr -
> > > len(DEFINE_STR + LANGUAGE_NAME_STRING_NAME)) +
> > > DecToHexStr(0, 4) + COMMENT_NOT_REFERENCED
> > >      Str = WriteLine(Str, Line)
> > >      Line = COMMENT_DEFINE_STR + ' ' +
> > > PRINTABLE_LANGUAGE_NAME_STRING_NAME + ' ' *
> > > (ValueStartPtr - len(DEFINE_STR +
> > > PRINTABLE_LANGUAGE_NAME_STRING_NAME)) +
> DecToHexStr(1,
> > > 4) + COMMENT_NOT_REFERENCED
> > >      Str = WriteLine(Str, Line)
> > > @@ -164,16 +164,16 @@ def
> CreateHFileContent(BaseName,
> > > UniObjectClass, IsCompatibleMode, UniGenCFlag):
> > >                      Line = COMMENT_DEFINE_STR + '
> ' +
> > > Name + ' ' + DecToHexStr(Token, 4) +
> > > COMMENT_NOT_REFERENCED
> > >                  else:
> > >                      Line = COMMENT_DEFINE_STR + '
> ' +
> > > Name + ' ' * (ValueStartPtr - len(DEFINE_STR +
> Name)) +
> > > DecToHexStr(Token, 4) + COMMENT_NOT_REFERENCED
> > >                  UnusedStr = WriteLine(UnusedStr,
> Line)
> > >
> > > -    Str = ''.join([Str, UnusedStr])
> > > +    Str.extend( UnusedStr)
> > >
> > >      Str = WriteLine(Str, '')
> > >      if IsCompatibleMode or UniGenCFlag:
> > >          Str = WriteLine(Str, 'extern unsigned char
> ' +
> > > BaseName + 'Strings[];')
> > > -    return Str
> > > +    return "".join(Str)
> > >
> > >  ## Create a complete .h file
> > >  #
> > >  # Create a complet .h file with file header and
> file
> > > content
> > >  #
> > > @@ -185,11 +185,11 @@ def
> CreateHFileContent(BaseName,
> > > UniObjectClass, IsCompatibleMode, UniGenCFlag):
> > >  # @retval Str:           A string of complete .h
> file
> > >  #
> > >  def CreateHFile(BaseName, UniObjectClass,
> > > IsCompatibleMode, UniGenCFlag):
> > >      HFile = WriteLine('',
> CreateHFileContent(BaseName,
> > > UniObjectClass, IsCompatibleMode, UniGenCFlag))
> > >
> > > -    return HFile
> > > +    return "".join(HFile)
> > >
> > >  ## Create a buffer to store all items in an array
> > >  #
> > >  # @param BinBuffer   Buffer to contain Binary
> data.
> > >  # @param Array:      The array need to be
> formatted
> > > @@ -209,11 +209,11 @@ def
> CreateBinBuffer(BinBuffer,
> > > Array):
> > >  #
> > >  def CreateArrayItem(Array, Width = 16):
> > >      MaxLength = Width
> > >      Index = 0
> > >      Line = '  '
> > > -    ArrayItem = ''
> > > +    ArrayItem = []
> > >
> > >      for Item in Array:
> > >          if Index < MaxLength:
> > >              Line = Line + Item + ',  '
> > >              Index = Index + 1
> > > @@ -221,11 +221,11 @@ def CreateArrayItem(Array,
> Width
> > > = 16):
> > >              ArrayItem = WriteLine(ArrayItem, Line)
> > >              Line = '  ' + Item + ',  '
> > >              Index = 1
> > >      ArrayItem = Write(ArrayItem, Line.rstrip())
> > >
> > > -    return ArrayItem
> > > +    return "".join(ArrayItem)
> > >
> > >  ## CreateCFileStringValue
> > >  #
> > >  # Create a line with string value
> > >  #
> > > @@ -236,11 +236,11 @@ def CreateArrayItem(Array,
> Width
> > > = 16):
> > >
> > >  def CreateCFileStringValue(Value):
> > >      Value = [StringBlockType] + Value
> > >      Str = WriteLine('', CreateArrayItem(Value))
> > >
> > > -    return Str
> > > +    return "".join(Str)
> > >
> > >  ## GetFilteredLanguage
> > >  #
> > >  # apply get best language rules to the UNI
> language
> > > code list
> > >  #
> > > @@ -438,11 +438,11 @@ def
> CreateCFileContent(BaseName,
> > > UniObjectClass, IsCompatibleMode, UniBinBuffer,
> > >      #
> > >      # Join package data
> > >      #
> > >      AllStr = Write(AllStr, Str)
> > >
> > > -    return AllStr
> > > +    return "".join(AllStr)
> > >
> > >  ## Create end of .c file
> > >  #
> > >  # Create end of .c file
> > >  #
> > > @@ -465,11 +465,11 @@ def CreateCFileEnd():
> > >  #
> > >  def CreateCFile(BaseName, UniObjectClass,
> > > IsCompatibleMode, FilterInfo):
> > >      CFile = ''
> > >      CFile = WriteLine(CFile,
> > > CreateCFileContent(BaseName, UniObjectClass,
> > > IsCompatibleMode, None, FilterInfo))
> > >      CFile = WriteLine(CFile, CreateCFileEnd())
> > > -    return CFile
> > > +    return "".join(CFile)
> > >
> > >  ## GetFileList
> > >  #
> > >  # Get a list for all files
> > >  #
> > > @@ -572,17 +572,34 @@ def
> GetStringFiles(UniFilList,
> > > SourceFileList, IncludeList, IncludePathList, Ski
> > >
> > >  #
> > >  # Write an item
> > >  #
> > >  def Write(Target, Item):
> > > -    return ''.join([Target, Item])
> > > +    if isinstance(Target,str):
> > > +        Target = [Target]
> > > +    if not Target:
> > > +        Target = []
> > > +    if isinstance(Item,list):
> > > +        Target.extend(Item)
> > > +    else:
> > > +        Target.append(Item)
> > > +    return Target
> > >
> > >  #
> > >  # Write an item with a break line
> > >  #
> > >  def WriteLine(Target, Item):
> > > -    return ''.join([Target, Item, '\n'])
> > > +    if isinstance(Target,str):
> > > +        Target = [Target]
> > > +    if not Target:
> > > +        Target = []
> > > +    if isinstance(Item, list):
> > > +        Target.extend(Item)
> > > +    else:
> > > +        Target.append(Item)
> > > +    Target.append('\n')
> > > +    return Target
> > >
> > >  # This acts like the main() function for the
> script,
> > > unless it is 'import'ed into another
> > >  # script.
> > >  if __name__ == '__main__':
> > >      EdkLogger.info('start')
> > > diff --git a/BaseTools/Source/Python/Common/Misc.py
> > > b/BaseTools/Source/Python/Common/Misc.py
> > > index 80236db160..8dcbe141ae 100644
> > > --- a/BaseTools/Source/Python/Common/Misc.py
> > > +++ b/BaseTools/Source/Python/Common/Misc.py
> > > @@ -777,21 +777,21 @@ class TemplateString(object):
> > >
> > >              return "".join(StringList)
> > >
> > >      ## Constructor
> > >      def __init__(self, Template=None):
> > > -        self.String = ''
> > > +        self.String = []
> > >          self.IsBinary = False
> > >          self._Template = Template
> > >          self._TemplateSectionList =
> > > self._Parse(Template)
> > >
> > >      ## str() operator
> > >      #
> > >      #   @retval     string  The string replaced
> > >      #
> > >      def __str__(self):
> > > -        return self.String
> > > +        return "".join(self.String)
> > >
> > >      ## Split the template string into fragments
> per
> > > the ${BEGIN} and ${END} flags
> > >      #
> > >      #   @retval     list    A list of
> > > TemplateString.Section objects
> > >      #
> > > @@ -835,13 +835,16 @@ class TemplateString(object):
> > >      #   @param      Dictionary      The
> placeholder
> > > dictionaries
> > >      #
> > >      def Append(self, AppendString,
> Dictionary=None):
> > >          if Dictionary:
> > >              SectionList =
> self._Parse(AppendString)
> > > -            self.String +=
> > > "".join(S.Instantiate(Dictionary) for S in
> SectionList)
> > > +            self.String.append(
> > > "".join(S.Instantiate(Dictionary) for S in
> > > SectionList))
> > >          else:
> > > -            self.String += AppendString
> > > +            if isinstance(AppendString,list):
> > > +                self.String.extend(AppendString)
> > > +            else:
> > > +                self.String.append(AppendString)
> > >
> > >      ## Replace the string template with dictionary
> of
> > > placeholders
> > >      #
> > >      #   @param      Dictionary      The
> placeholder
> > > dictionaries
> > >      #
> > > @@ -1741,27 +1744,21 @@ class PathClass(object):
> > >      #
> > >      # @retval False The two PathClass are
> different
> > >      # @retval True  The two PathClass are the same
> > >      #
> > >      def __eq__(self, Other):
> > > -        if isinstance(Other, type(self)):
> > > -            return self.Path == Other.Path
> > > -        else:
> > > -            return self.Path == str(Other)
> > > +        return self.Path == str(Other)
> > >
> > >      ## Override __cmp__ function
> > >      #
> > >      # Customize the comparsion operation of two
> > > PathClass
> > >      #
> > >      # @retval 0     The two PathClass are
> different
> > >      # @retval -1    The first PathClass is less
> than
> > > the second PathClass
> > >      # @retval 1     The first PathClass is Bigger
> than
> > > the second PathClass
> > >      def __cmp__(self, Other):
> > > -        if isinstance(Other, type(self)):
> > > -            OtherKey = Other.Path
> > > -        else:
> > > -            OtherKey = str(Other)
> > > +        OtherKey = str(Other)
> > >
> > >          SelfKey = self.Path
> > >          if SelfKey == OtherKey:
> > >              return 0
> > >          elif SelfKey > OtherKey:
> > > diff --git
> > > a/BaseTools/Source/Python/Workspace/InfBuildData.py
> > > b/BaseTools/Source/Python/Workspace/InfBuildData.py
> > > index 44d44d24eb..d615cccdf7 100644
> > > ---
> a/BaseTools/Source/Python/Workspace/InfBuildData.py
> > > +++
> b/BaseTools/Source/Python/Workspace/InfBuildData.py
> > > @@ -612,11 +612,13 @@ class
> > > InfBuildData(ModuleBuildClassObject):
> > >          for Record in RecordList:
> > >              Lib = Record[0]
> > >              Instance = Record[1]
> > >              if Instance:
> > >                  Instance = NormPath(Instance,
> > > self._Macros)
> > > -            RetVal[Lib] = Instance
> > > +                RetVal[Lib] = Instance
> > > +            else:
> > > +                RetVal[Lib] = None
> > >          return RetVal
> > >
> > >      ## Retrieve library names (for Edk.x style of
> > > modules)
> > >      @cached_property
> > >      def Libraries(self):
> > > diff --git
> > >
> a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
> > >
> b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
> > > index 8d8a3e2789..55d01fa4b2 100644
> > > ---
> > >
> a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
> > > +++
> > >
> b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
> > > @@ -126,17 +126,14 @@ def
> GetModuleLibInstances(Module,
> > > Platform, BuildDatabase, Arch, Target, Toolcha
> > >      while len(LibraryConsumerList) > 0:
> > >          M = LibraryConsumerList.pop()
> > >          for LibraryClassName in M.LibraryClasses:
> > >              if LibraryClassName not in
> > > LibraryInstance:
> > >                  # override library instance for
> this
> > > module
> > > -                if LibraryClassName in
> > > Platform.Modules[str(Module)].LibraryClasses:
> > > -                    LibraryPath =
> > >
> Platform.Modules[str(Module)].LibraryClasses[LibraryCla
> > > ssName]
> > > -                else:
> > > -                    LibraryPath =
> > > Platform.LibraryClasses[LibraryClassName,
> ModuleType]
> > > -                if LibraryPath is None or
> LibraryPath
> > > == "":
> > > -                    LibraryPath =
> > > M.LibraryClasses[LibraryClassName]
> > > -                    if LibraryPath is None or
> > > LibraryPath == "":
> > > +                LibraryPath =
> > >
> Platform.Modules[str(Module)].LibraryClasses.get(Librar
> > >
> yClassName,Platform.LibraryClasses[LibraryClassName,
> > > ModuleType])
> > > +                if LibraryPath is None:
> > > +                    LibraryPath =
> > > M.LibraryClasses.get(LibraryClassName)
> > > +                    if LibraryPath is None:
> > >                          if FileName:
> > >
> EdkLogger.error("build",
> > > RESOURCE_NOT_AVAILABLE,
> > >
> "Instance
> > > of library class [%s] is not found" %
> LibraryClassName,
> > >
> > > File=FileName,
> > >
> > > ExtraData="in [%s] [%s]\n\tconsumed by module [%s]"
> %
> > > (str(M), Arch, str(Module)))
> > > --
> > > 2.19.1.windows.1
> > >
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel


  reply	other threads:[~2018-11-09 17:01 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-08 10:16 [Patch] BaseTools: Optimize string concatenation BobCF
2018-11-08 15:26 ` Carsey, Jaben
2018-11-08 16:40 ` Kinney, Michael D
2018-11-09 14:16   ` Gao, Liming
2018-11-09 17:01     ` Kinney, Michael D [this message]
2018-11-08 16:52 ` Leif Lindholm
2018-11-09  3:25   ` Feng, Bob C
2018-11-09 11:48     ` Leif Lindholm
2018-11-11  0:41       ` Feng, Bob C
2018-12-05  2:51         ` Feng, Bob C
2018-12-10 10:47           ` Leif Lindholm
2018-12-10 12:09             ` Feng, Bob C
2018-12-10 12:35               ` Leif Lindholm
2018-12-11  8:48                 ` Feng, Bob C
2018-12-12 18:37                   ` Leif Lindholm
2018-12-13  1:50                     ` Gao, Liming
2018-12-13 10:08                       ` Leif Lindholm
2018-12-13 14:01                         ` Gao, Liming

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E92EE9817A31E24EB0585FDF735412F5B8B2DA93@ORSMSX113.amr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox