[Python-checkins] python/dist/src/Lib pickle.py,1.95,1.96

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Mon, 27 Jan 2003 19:03:12 -0800


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv27673

Modified Files:
	pickle.py 
Log Message:
Got rid of mdumps; I timed it, and struct.pack("<i", x) is more than
40% faster than marshal.dumps(x)[1:]!  (That's not counting the
module attribute lookups, which can be avoided in either case.)


Index: pickle.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v
retrieving revision 1.95
retrieving revision 1.96
diff -C2 -d -r1.95 -r1.96
*** pickle.py	28 Jan 2003 02:09:55 -0000	1.95
--- pickle.py	28 Jan 2003 03:03:08 -0000	1.96
***************
*** 46,50 ****
                        ]                 # Old format versions we can read
  
- mdumps = marshal.dumps
  mloads = marshal.loads
  
--- 46,49 ----
***************
*** 221,243 ****
  
      # Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i.
!     def put(self, i):
          if self.bin:
-             s = mdumps(i)[1:]
              if i < 256:
!                 return BINPUT + s[0]
! 
!             return LONG_BINPUT + s
  
          return PUT + `i` + '\n'
  
      # Return a GET (BINGET, LONG_BINGET) opcode string, with argument i.
!     def get(self, i):
          if self.bin:
-             s = mdumps(i)[1:]
- 
              if i < 256:
!                 return BINGET + s[0]
! 
!             return LONG_BINGET + s
  
          return GET + `i` + '\n'
--- 220,239 ----
  
      # Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i.
!     def put(self, i, pack=struct.pack):
          if self.bin:
              if i < 256:
!                 return BINPUT + chr(i)
!             else:
!                 return LONG_BINPUT + pack("<i", i)
  
          return PUT + `i` + '\n'
  
      # Return a GET (BINGET, LONG_BINGET) opcode string, with argument i.
!     def get(self, i, pack=struct.pack):
          if self.bin:
              if i < 256:
!                 return BINGET + chr(i)
!             else:
!                 return LONG_BINGET + pack("<i", i)
  
          return GET + `i` + '\n'
***************
*** 363,384 ****
      dispatch[bool] = save_bool
  
!     def save_int(self, object):
          if self.bin:
              # If the int is small enough to fit in a signed 4-byte 2's-comp
              # format, we can store it more efficiently than the general
              # case.
              high_bits = object >> 31  # note that Python shift sign-extends
              if  high_bits == 0 or high_bits == -1:
                  # All high bits are copies of bit 2**31, so the value
                  # fits in a 4-byte signed int.
!                 i = mdumps(object)[1:]
!                 assert len(i) == 4
!                 if i[-2:] == '\000\000':    # fits in 2-byte unsigned int
!                     if i[-3] == '\000':     # fits in 1-byte unsigned int
!                         self.write(BININT1 + i[0])
!                     else:
!                         self.write(BININT2 + i[:2])
!                 else:
!                     self.write(BININT + i)
                  return
          # Text pickle, or int too big to fit in signed 4-byte format.
--- 359,381 ----
      dispatch[bool] = save_bool
  
!     def save_int(self, object, pack=struct.pack):
          if self.bin:
              # If the int is small enough to fit in a signed 4-byte 2's-comp
              # format, we can store it more efficiently than the general
              # case.
+             # First one- and two-byte unsigned ints:
+             if object >= 0:
+                 if object < 0xff:
+                     self.write(BININT1 + chr(object))
+                     return
+                 if object < 0xffff:
+                     self.write(BININT2 + chr(object&0xff) + chr(object>>8))
+                     return
+             # Next check for 4-byte signed ints:
              high_bits = object >> 31  # note that Python shift sign-extends
              if  high_bits == 0 or high_bits == -1:
                  # All high bits are copies of bit 2**31, so the value
                  # fits in a 4-byte signed int.
!                 self.write(BININT + pack("<i", object))
                  return
          # Text pickle, or int too big to fit in signed 4-byte format.
***************
*** 397,401 ****
      dispatch[FloatType] = save_float
  
!     def save_string(self, object):
          if self.bin:
              n = len(object)
--- 394,398 ----
      dispatch[FloatType] = save_float
  
!     def save_string(self, object, pack=struct.pack):
          if self.bin:
              n = len(object)
***************
*** 403,407 ****
                  self.write(SHORT_BINSTRING + chr(n) + object)
              else:
!                 self.write(BINSTRING + mdumps(n)[1:] + object)
          else:
              self.write(STRING + `object` + '\n')
--- 400,404 ----
                  self.write(SHORT_BINSTRING + chr(n) + object)
              else:
!                 self.write(BINSTRING + pack("<i", n) + object)
          else:
              self.write(STRING + `object` + '\n')
***************
*** 409,418 ****
      dispatch[StringType] = save_string
  
!     def save_unicode(self, object):
          if self.bin:
              encoding = object.encode('utf-8')
              n = len(encoding)
!             s = mdumps(n)[1:]
!             self.write(BINUNICODE + s + encoding)
          else:
              object = object.replace("\\", "\\u005c")
--- 406,414 ----
      dispatch[StringType] = save_string
  
!     def save_unicode(self, object, pack=struct.pack):
          if self.bin:
              encoding = object.encode('utf-8')
              n = len(encoding)
!             self.write(BINUNICODE + pack("<i", n) + encoding)
          else:
              object = object.replace("\\", "\\u005c")
***************
*** 424,428 ****
      if StringType == UnicodeType:
          # This is true for Jython
!         def save_string(self, object):
              unicode = object.isunicode()
  
--- 420,424 ----
      if StringType == UnicodeType:
          # This is true for Jython
!         def save_string(self, object, pack=struct.pack):
              unicode = object.isunicode()
  
***************
*** 431,438 ****
                      object = object.encode("utf-8")
                  l = len(object)
-                 s = mdumps(l)[1:]
                  if l < 256 and not unicode:
!                     self.write(SHORT_BINSTRING + s[0] + object)
                  else:
                      if unicode:
                          self.write(BINUNICODE + s + object)
--- 427,434 ----
                      object = object.encode("utf-8")
                  l = len(object)
                  if l < 256 and not unicode:
!                     self.write(SHORT_BINSTRING + chr(l) + object)
                  else:
+                     s = pack("<i", l)
                      if unicode:
                          self.write(BINUNICODE + s + object)