]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools/GenFds: speed up Region.PadBuffer()
authorLaszlo Ersek <lersek@redhat.com>
Mon, 11 Jul 2016 14:26:31 +0000 (16:26 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Tue, 12 Jul 2016 11:19:27 +0000 (13:19 +0200)
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 <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
BaseTools/Source/Python/GenFds/Region.py

index 6769b39ba7e83ee976a21a54449771c307bd2fb7..7548a4f014b1397be4bb6cfbb3b7b287119d06fc 100644 (file)
@@ -18,6 +18,7 @@
 from struct import *\r
 from GenFdsGlobalVariable import GenFdsGlobalVariable\r
 import StringIO\r
+import string\r
 from CommonDataClass.FdfClass import RegionClassObject\r
 import Common.LongFilePathOs as os\r
 from stat import *\r
@@ -52,11 +53,11 @@ class Region(RegionClassObject):
     def PadBuffer(self, Buffer, ErasePolarity, Size):\r
         if Size > 0:\r
             if (ErasePolarity == '1') :\r
-                PadData = 0xFF\r
+                PadByte = pack('B', 0xFF)\r
             else:\r
-                PadData = 0\r
-            for i in range(0, Size):\r
-                Buffer.write(pack('B', PadData))\r
+                PadByte = pack('B', 0)\r
+            PadData = string.join(PadByte for i in xrange(0, Size))\r
+            Buffer.write(PadData)\r
 \r
     ## AddToBuffer()\r
     #\r