正文
i
in
xrange
(
count
)
:
cur
.
execute
(
'insert into test values(?, ?, ?)'
,
(
i
-
1
,
i
,
i
+
1
))
@
timeit
def test_sqlite_query
(
cur
,
des
=
''
)
:
for
i
in
xrange
(
count
)
:
cur
.
execute
(
'select * from test where a=? and b=?'
,
(
i
-
1
,
i
))
print
'-------pydblite--------'
import pydblite
pydb
=
pydblite
.
Base
(
':memory:'
)
pydb
.
create
(
'a'
,
'b'
,
'c'
)
pydb
.
create_index
(
'a'
,
'b'
)
test_insert
(
pydb
,
des
=
'insert'
)
test_query_object
(
pydb
,
des
=
'query, object call'
)
print
'-------sqlite3--------'
import sqlite3
con
=
sqlite3
.
connect
(
':memory:'
)
cur
=
con
.
cursor
()
cur
.
execute
(
'create table test (a char(256), b char(256), c char(256));'
)
cur
.
execute
(
'create index a_index on test(a)'
)
cur
.
execute
(
'create index b_index on test(b)'
)
test_sqlite_insert
(
cur
,
des
=
'insert'
)
test_sqlite_query
(
cur
,
des
=
'query'
)
在创建索引的情况下,10w次的插入和查询的时间如下:
-------
pydblite
--------
1.14199995995
insert
0.308000087738
query
,
object
call
-------
sqlite3
--------
0.411999940872
insert
0.30999994278
query
在未创建索引的情况(把创建索引的测试语句注释掉)下,1w次的插入和查询时间如下:
-------
pydblite
--------
0.0989999771118
insert
5.15300011635
query
,
object
call
-------
sqlite3
--------
0.0169999599457
insert
7.43400001526
query
我们不难得出如下结论:
sqlite的插入速度是pydblite的3-5倍;而在建立索引的情况下,sqlite的查询速度和pydblite相当;在未建立索引的情况下,sqlite的查询速度比pydblite慢1.5倍左右。
3 优化
我们的目标非常明确,使用Pythonic的内存数据库,提高插入和查询效率,而不考虑持久化。那么能否既拥有pydblite的pythonic的使用方式,又同时具备pydblite和sqlite中插入和查询速度快的那一方的速度?针对我们的目标,看看能否对pydblite做一些优化。
阅读pydblite的源码,首先映入眼帘的是对python2和3做了一个简单的区分。给外部调用的Base基于_BasePy2或者_BasePy3,它们仅仅是在__iter__上有细微差异,最终调用的是_Base这个类。
class
_BasePy2
(
_Base
)
:
def __iter__
(
self
)
:
"""Iteration on the records"""
return
iter
(
self
.
records
.
itervalues
())
class
_BasePy3
(
_Base
)
:
def __iter__
(
self
)
:
"""Iteration on the records"""
return
iter
(
self
.
records
.
values
())
if
sys
.
version_info
[
0
]
==
2
:
Base
=
_BasePy2
else
:
Base
=
_BasePy3