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>
Reviewed-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
This commit is contained in:
BobCF 2018-11-08 18:16:25 +08:00
parent 2f818ed0fb
commit 4e37570739
4 changed files with 44 additions and 31 deletions

View File

@ -137,7 +137,7 @@ def AscToHexList(Ascii):
# @retval Str: A string of .h file content # @retval Str: A string of .h file content
# #
def CreateHFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag): def CreateHFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag):
Str = '' Str = []
ValueStartPtr = 60 ValueStartPtr = 60
Line = COMMENT_DEFINE_STR + ' ' + LANGUAGE_NAME_STRING_NAME + ' ' * (ValueStartPtr - len(DEFINE_STR + LANGUAGE_NAME_STRING_NAME)) + DecToHexStr(0, 4) + COMMENT_NOT_REFERENCED 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) Str = WriteLine(Str, Line)
@ -166,12 +166,12 @@ def CreateHFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag):
Line = COMMENT_DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4) + COMMENT_NOT_REFERENCED Line = COMMENT_DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4) + COMMENT_NOT_REFERENCED
UnusedStr = WriteLine(UnusedStr, Line) UnusedStr = WriteLine(UnusedStr, Line)
Str = ''.join([Str, UnusedStr]) Str.extend( UnusedStr)
Str = WriteLine(Str, '') Str = WriteLine(Str, '')
if IsCompatibleMode or UniGenCFlag: if IsCompatibleMode or UniGenCFlag:
Str = WriteLine(Str, 'extern unsigned char ' + BaseName + 'Strings[];') Str = WriteLine(Str, 'extern unsigned char ' + BaseName + 'Strings[];')
return Str return "".join(Str)
## Create a complete .h file ## Create a complete .h file
# #
@ -187,7 +187,7 @@ def CreateHFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag):
def CreateHFile(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag): def CreateHFile(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag):
HFile = WriteLine('', CreateHFileContent(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 ## Create a buffer to store all items in an array
# #
@ -211,7 +211,7 @@ def CreateArrayItem(Array, Width = 16):
MaxLength = Width MaxLength = Width
Index = 0 Index = 0
Line = ' ' Line = ' '
ArrayItem = '' ArrayItem = []
for Item in Array: for Item in Array:
if Index < MaxLength: if Index < MaxLength:
@ -223,7 +223,7 @@ def CreateArrayItem(Array, Width = 16):
Index = 1 Index = 1
ArrayItem = Write(ArrayItem, Line.rstrip()) ArrayItem = Write(ArrayItem, Line.rstrip())
return ArrayItem return "".join(ArrayItem)
## CreateCFileStringValue ## CreateCFileStringValue
# #
@ -238,7 +238,7 @@ def CreateCFileStringValue(Value):
Value = [StringBlockType] + Value Value = [StringBlockType] + Value
Str = WriteLine('', CreateArrayItem(Value)) Str = WriteLine('', CreateArrayItem(Value))
return Str return "".join(Str)
## GetFilteredLanguage ## GetFilteredLanguage
# #
@ -440,7 +440,7 @@ def CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniBinBuffer,
# #
AllStr = Write(AllStr, Str) AllStr = Write(AllStr, Str)
return AllStr return "".join(AllStr)
## Create end of .c file ## Create end of .c file
# #
@ -467,7 +467,7 @@ def CreateCFile(BaseName, UniObjectClass, IsCompatibleMode, FilterInfo):
CFile = '' CFile = ''
CFile = WriteLine(CFile, CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, None, FilterInfo)) CFile = WriteLine(CFile, CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, None, FilterInfo))
CFile = WriteLine(CFile, CreateCFileEnd()) CFile = WriteLine(CFile, CreateCFileEnd())
return CFile return "".join(CFile)
## GetFileList ## GetFileList
# #
@ -574,13 +574,30 @@ def GetStringFiles(UniFilList, SourceFileList, IncludeList, IncludePathList, Ski
# Write an item # Write an item
# #
def Write(Target, 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 # Write an item with a break line
# #
def WriteLine(Target, Item): 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 # This acts like the main() function for the script, unless it is 'import'ed into another
# script. # script.

View File

@ -778,7 +778,7 @@ class TemplateString(object):
## Constructor ## Constructor
def __init__(self, Template=None): def __init__(self, Template=None):
self.String = '' self.String = []
self.IsBinary = False self.IsBinary = False
self._Template = Template self._Template = Template
self._TemplateSectionList = self._Parse(Template) self._TemplateSectionList = self._Parse(Template)
@ -788,7 +788,7 @@ class TemplateString(object):
# @retval string The string replaced # @retval string The string replaced
# #
def __str__(self): def __str__(self):
return self.String return "".join(self.String)
## Split the template string into fragments per the ${BEGIN} and ${END} flags ## Split the template string into fragments per the ${BEGIN} and ${END} flags
# #
@ -836,9 +836,12 @@ class TemplateString(object):
def Append(self, AppendString, Dictionary=None): def Append(self, AppendString, Dictionary=None):
if Dictionary: if Dictionary:
SectionList = self._Parse(AppendString) 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: 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 ## Replace the string template with dictionary of placeholders
# #
@ -1744,10 +1747,7 @@ class PathClass(object):
# @retval True The two PathClass are the same # @retval True The two PathClass are the same
# #
def __eq__(self, Other): def __eq__(self, Other):
if isinstance(Other, type(self)): return self.Path == str(Other)
return self.Path == Other.Path
else:
return self.Path == str(Other)
## Override __cmp__ function ## Override __cmp__ function
# #
@ -1757,10 +1757,7 @@ class PathClass(object):
# @retval -1 The first PathClass is less than the second PathClass # @retval -1 The first PathClass is less than the second PathClass
# @retval 1 The first PathClass is Bigger than the second PathClass # @retval 1 The first PathClass is Bigger than the second PathClass
def __cmp__(self, Other): def __cmp__(self, Other):
if isinstance(Other, type(self)): OtherKey = str(Other)
OtherKey = Other.Path
else:
OtherKey = str(Other)
SelfKey = self.Path SelfKey = self.Path
if SelfKey == OtherKey: if SelfKey == OtherKey:

View File

@ -614,7 +614,9 @@ class InfBuildData(ModuleBuildClassObject):
Instance = Record[1] Instance = Record[1]
if Instance: if Instance:
Instance = NormPath(Instance, self._Macros) Instance = NormPath(Instance, self._Macros)
RetVal[Lib] = Instance RetVal[Lib] = Instance
else:
RetVal[Lib] = None
return RetVal return RetVal
## Retrieve library names (for Edk.x style of modules) ## Retrieve library names (for Edk.x style of modules)

View File

@ -128,13 +128,10 @@ def GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolcha
for LibraryClassName in M.LibraryClasses: for LibraryClassName in M.LibraryClasses:
if LibraryClassName not in LibraryInstance: if LibraryClassName not in LibraryInstance:
# override library instance for this module # override library instance for this module
if LibraryClassName in Platform.Modules[str(Module)].LibraryClasses: LibraryPath = Platform.Modules[str(Module)].LibraryClasses.get(LibraryClassName,Platform.LibraryClasses[LibraryClassName, ModuleType])
LibraryPath = Platform.Modules[str(Module)].LibraryClasses[LibraryClassName] if LibraryPath is None:
else: LibraryPath = M.LibraryClasses.get(LibraryClassName)
LibraryPath = Platform.LibraryClasses[LibraryClassName, ModuleType] if LibraryPath is None:
if LibraryPath is None or LibraryPath == "":
LibraryPath = M.LibraryClasses[LibraryClassName]
if LibraryPath is None or LibraryPath == "":
if FileName: if FileName:
EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
"Instance of library class [%s] is not found" % LibraryClassName, "Instance of library class [%s] is not found" % LibraryClassName,