Skip to content

Commit fb25a04

Browse files
author
ARF
committed
__shapeIndex optimization: use numpy when available for array arithmetic
x378 speedup over master with numpy available x22 speedup over master without numpy
1 parent eec5efe commit fb25a04

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

shapefile.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
import tempfile
1919
import itertools
2020

21+
try:
22+
import numpy
23+
has_numpy = True
24+
except ImportError:
25+
has_numpy = False
26+
2127
try:
2228
memoryview(b'')
2329
except NameError:
@@ -227,7 +233,7 @@ def __init__(self, *args, **kwargs):
227233
self.shx = None
228234
self.dbf = None
229235
self.shapeName = "Not specified"
230-
self._offsets = []
236+
self._offsets = None
231237
self.shpLength = None
232238
self.numRecords = None
233239
self.fields = []
@@ -387,19 +393,22 @@ def __shapeIndex(self, i=None):
387393
shx = self.shx
388394
if not shx:
389395
return None
390-
if not self._offsets:
396+
if self._offsets is None:
391397
# File length (16-bit word * 2 = bytes) - header length
392398
shx.seek(24)
393399
shxRecordLength = (unpack(">i", shx.read(4))[0] * 2) - 100
394400
numRecords = shxRecordLength // 8
395401
# Jump to the first record.
396402
shx.seek(100)
397-
shxRecords = array.array('i')
398-
shxRecords.fromfile(shx, 2 * numRecords)
399-
if sys.byteorder != 'big':
400-
shxRecords.byteswap()
401403
# Offsets are 16-bit words just like the file length
402-
self._offsets = [2 * el for el in memoryview(shxRecords)[::2]]
404+
if has_numpy:
405+
self._offsets = numpy.fromfile(shx, '>i4', 2 * numRecords)[::2] * 2
406+
else:
407+
shxRecords = array.array('i')
408+
shxRecords.fromfile(shx, 2 * numRecords)
409+
if sys.byteorder != 'big':
410+
shxRecords.byteswap()
411+
self._offsets = [2 * el for el in memoryview(shxRecords)[::2]]
403412
if not i == None:
404413
return self._offsets[i]
405414

0 commit comments

Comments
 (0)