From bd907fb6386560e621112beca7b7d381d0003967 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Mon, 11 Jul 2016 16:26:31 +0200 Subject: [PATCH] BaseTools/GenFds: speed up Region.PadBuffer() The current implementation calls both pack() and Buffer.write() Size times. The new implementation calls both of these methods only once; the full data to write are constructed locally [1]. The range() function is replaced by xrange() because the latter is supposed to be faster / lighter weight [2]. On my laptop, I tested the change as follows: I pre-built the series at [3] with build -a X64 -p OvmfPkg/OvmfPkgX64.dsc -t GCC48 -b DEBUG \ -D HTTP_BOOT_ENABLE -D SECURE_BOOT_ENABLE (The series at [3] is relevant because it increases the size of one of the padded regions by 8.5 MB, slowing down the build quite a bit.) With all source code already compiled, repeating the above command takes approximately 45 seconds. With the patch applied, it goes down to 29 seconds. [1] http://stackoverflow.com/questions/27384093/fastest-way-to-write-huge-data-in-file [2] https://docs.python.org/2/library/functions.html?highlight=xrange#xrange [3] http://thread.gmane.org/gmane.comp.bios.edk2.devel/14214 We can also measure the impact with a synthetic test: > import timeit > > test_old = """ > import struct, string, StringIO > Size = (8 * 1024 + 512) * 1024 > Buffer = StringIO.StringIO() > PadData = 0xFF > for i in range(0, Size): > Buffer.write(struct.pack('B', PadData)) > """ > > test_new = """ > import struct, string, StringIO > Size = (8 * 1024 + 512) * 1024 > Buffer = StringIO.StringIO() > PadByte = struct.pack('B', 0xFF) > PadData = string.join(PadByte for i in xrange(0, Size)) > Buffer.write(PadData) > """ > > print(timeit.repeat(stmt=test_old, number=1, repeat=3)) > print(timeit.repeat(stmt=test_new, number=1, repeat=3)) The output is [8.231637001037598, 8.81188416481018, 8.948754072189331] [0.5503702163696289, 0.5461571216583252, 0.578315019607544] Cc: Yonghong Zhu Cc: Liming Gao Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Reviewed-by: Liming Gao --- BaseTools/Source/Python/GenFds/Region.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/BaseTools/Source/Python/GenFds/Region.py b/BaseTools/Source/Python/GenFds/Region.py index 6769b39ba7..7548a4f014 100644 --- a/BaseTools/Source/Python/GenFds/Region.py +++ b/BaseTools/Source/Python/GenFds/Region.py @@ -18,6 +18,7 @@ from struct import * from GenFdsGlobalVariable import GenFdsGlobalVariable import StringIO +import string from CommonDataClass.FdfClass import RegionClassObject import Common.LongFilePathOs as os from stat import * @@ -52,11 +53,11 @@ class Region(RegionClassObject): def PadBuffer(self, Buffer, ErasePolarity, Size): if Size > 0: if (ErasePolarity == '1') : - PadData = 0xFF + PadByte = pack('B', 0xFF) else: - PadData = 0 - for i in range(0, Size): - Buffer.write(pack('B', PadData)) + PadByte = pack('B', 0) + PadData = string.join(PadByte for i in xrange(0, Size)) + Buffer.write(PadData) ## AddToBuffer() # -- 2.39.2