Skip to content

Commit 977e666

Browse files
committed
Initial improvements to get rid of the performance regression in py3.
Byte buffer concatenations are considerably slower here for some reason. Also there was no need for the memorybuffer.
1 parent fda3285 commit 977e666

6 files changed

Lines changed: 30 additions & 29 deletions

File tree

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
language: python
22
python:
3+
- 2.4
4+
- 2.5
35
- 2.6
46
- 2.7
57
- 3.3

README.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,15 @@ For performance critical 64 bit applications, a simplified version of memory map
2525

2626
## Prerequisites
2727

28-
* Python 2.4, 2.5 or 2.6
28+
* Python 2.4, 2.5, 2.6, 2.7 or 3.3
2929
* OSX, Windows or Linux
3030

3131
The package was tested on all of the previously mentioned configurations.
3232

33-
34-
3533
## Limitations
3634

3735
* The memory access is read-only by design.
3836
* In python below 2.6, memory maps will be created in compatibility mode which works, but creates inefficient memory mappings as they always start at offset 0.
39-
* It wasn't tested on python 2.7 and 3.x.
40-
4137

4238
## Installing smmap
4339

@@ -80,7 +76,6 @@ Issues can be filed on github:
8076
* https://github.com/Byron/smmap/issues
8177

8278

83-
8479
## License Information
8580

8681
*smmap* is licensed under the New BSD License.

doc/source/changes.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
Changelog
33
#########
44

5+
**********
6+
v0.8.2
7+
**********
8+
- Cleaned up code and assured it works sufficiently well with python 3
9+
510
**********
611
v0.8.1
712
**********
813
- A single bugfix
914

10-
1115
**********
1216
v0.8.0
1317
**********

smmap/buf.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,18 @@ def __getslice__(self, i, j):
7979
else:
8080
l = j-i # total length
8181
ofs = i
82-
# Keeping tokens in a list could possible be faster, but the list
83-
# overhead outweighs the benefits (tested) !
84-
md = bytes()
82+
# It's fastest to keep tokens and join later, especially in py3, which was 7 times slower
83+
# in the previous iteration of this code
84+
md = list()
8585
while l:
8686
c.use_region(ofs, l)
8787
assert c.is_valid()
8888
d = c.buffer()[:l]
8989
ofs += len(d)
9090
l -= len(d)
91-
md += d
91+
md.append(d)
9292
#END while there are bytes to read
93-
return md
93+
return bytes().join(md)
9494
# END fast or slow path
9595
#{ Interface
9696

smmap/mman.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
"""Module containing a memory memory manager which provides a sliding window on a number of memory mapped files"""
22
from .util import (
3-
MapWindow,
4-
MapRegion,
5-
MapRegionList,
6-
is_64_bit,
7-
align_to_mmap,
8-
string_types,
9-
buffer,
10-
)
3+
MapWindow,
4+
MapRegion,
5+
MapRegionList,
6+
is_64_bit,
7+
string_types,
8+
buffer,
9+
)
1110

1211
from weakref import ref
1312
import sys
@@ -261,14 +260,14 @@ class StaticWindowMapManager(object):
261260
def __init__(self, window_size = 0, max_memory_size = 0, max_open_handles = sys.maxsize):
262261
"""initialize the manager with the given parameters.
263262
:param window_size: if -1, a default window size will be chosen depending on
264-
the operating system's architechture. It will internally be quantified to a multiple of the page size
263+
the operating system's architecture. It will internally be quantified to a multiple of the page size
265264
If 0, the window may have any size, which basically results in mapping the whole file at one
266265
:param max_memory_size: maximum amount of memory we may map at once before releasing mapped regions.
267-
If 0, a viable default iwll be set dependning on the system's architecture.
266+
If 0, a viable default will be set depending on the system's architecture.
268267
It is a soft limit that is tried to be kept, but nothing bad happens if we have to overallocate
269-
:param max_open_handles: if not maxin, limit the amount of open file handles to the given number.
270-
Otherwise the amount is only limited by the system iteself. If a system or soft limit is hit,
271-
the manager will free as many handles as posisble"""
268+
:param max_open_handles: if not maxint, limit the amount of open file handles to the given number.
269+
Otherwise the amount is only limited by the system itself. If a system or soft limit is hit,
270+
the manager will free as many handles as possible"""
272271
self._fdict = dict()
273272
self._window_size = window_size
274273
self._max_memory_size = max_memory_size
@@ -277,15 +276,15 @@ def __init__(self, window_size = 0, max_memory_size = 0, max_open_handles = sys.
277276
self._handle_count = 0
278277

279278
if window_size < 0:
280-
coeff = 32
279+
coeff = 64
281280
if is_64_bit():
282281
coeff = 1024
283282
#END handle arch
284283
self._window_size = coeff * self._MB_in_bytes
285284
# END handle max window size
286285

287286
if max_memory_size == 0:
288-
coeff = 512
287+
coeff = 1024
289288
if is_64_bit():
290289
coeff = 8192
291290
#END handle arch

smmap/util.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
except NameError:
2424
# Python 3 has no `buffer`; only `memoryview`
2525
def buffer(obj, offset, size):
26-
return memoryview(obj[offset:offset+size])
27-
26+
# return memoryview(obj[offset:offset+size])
27+
# doing it directly is much faster !
28+
return obj[offset:offset+size]
2829

2930
def string_types():
3031
if sys.version_info[0] >= 3:

0 commit comments

Comments
 (0)