diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ab8002c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,85 @@
+MongoMallard
+============
+
+MongoMallard is a fast ORM-like layer on top of PyMongo, based on MongoEngine.
+
+* Repository: https://github.com/elasticsales/mongomallard
+* See [README_MONGOENGINE](https://github.com/elasticsales/mongomallard/blob/master/README_MONGOENGINE.rst) for MongoEngine's README.
+* See [DIFFERENCES](https://github.com/elasticsales/mongomallard/blob/master/DIFFERENCES.md) for differences between MongoEngine and MongoMallard.
+
+
+Benchmarks
+----------
+
+Sample run on a 2.7 GHz Intel Core i5 running OS X 10.8.3
+
+
+
+ |
+ MongoEngine 0.8.2 (ede9fcf) |
+ MongoMallard (478062c) |
+ Speedup |
+
+
+ | Doc initialization |
+ 52.494us |
+ 25.195us |
+ 2.08x |
+
+
+ | Doc getattr |
+ 1.339us |
+ 0.584us |
+ 2.29x |
+
+
+ | Doc setattr |
+ 3.064us |
+ 2.550us |
+ 1.20x |
+
+
+ | Doc to mongo |
+ 49.415us |
+ 26.497us |
+ 1.86x |
+
+
+ | Load from SON |
+ 61.475us |
+ 4.510us |
+ 13.63x |
+
+
+ | Save to database |
+ 434.389us |
+ 289.972us |
+ 2.29x |
+
+
+ | Load from database |
+ 558.178us |
+ 480.690us |
+ 1.16x |
+
+
+ | Save/delete big object to database |
+ 98.838ms |
+ 65.789ms |
+ 1.50x |
+
+
+ | Serialize big object from database |
+ 31.390ms |
+ 20.265ms |
+ 1.55x |
+
+
+ | Load big object from database |
+ 41.159ms |
+ 1.400ms |
+ 29.40x |
+
+
+
+See [tests/benchmark.py](https://github.com/elasticsales/mongomallard/blob/master/tests/benchmark.py) for source code.
diff --git a/README.rst b/README_MONGOENGINE.rst
similarity index 100%
rename from README.rst
rename to README_MONGOENGINE.rst
diff --git a/mongoengine/__init__.py b/mongoengine/__init__.py
index 5bd1201..875c916 100644
--- a/mongoengine/__init__.py
+++ b/mongoengine/__init__.py
@@ -16,6 +16,7 @@ __all__ = (list(document.__all__) + fields.__all__ + connection.__all__ +
list(queryset.__all__) + signals.__all__ + list(errors.__all__))
VERSION = (0, 8, 2)
+MALLARD = True
def get_version():
diff --git a/mongoengine/base/proxy.py b/mongoengine/base/proxy.py
index 4d92462..7d2879b 100644
--- a/mongoengine/base/proxy.py
+++ b/mongoengine/base/proxy.py
@@ -180,9 +180,6 @@ class DocumentProxy(LocalProxy):
def _get_current_object(self):
if self.__document == None:
- #print 'fetching', self.__document_type, self.__pk
- #import traceback
- #traceback.print_stack()
collection = self.__document_type._get_collection()
son = collection.find_one({'_id': self.__pk})
document = self.__document_type._from_son(son)
diff --git a/tests/benchmark.py b/tests/benchmark.py
new file mode 100644
index 0000000..89439f3
--- /dev/null
+++ b/tests/benchmark.py
@@ -0,0 +1,90 @@
+from mongoengine import *
+from timeit import repeat
+import unittest
+
+conn_settings = {
+ 'db': 'mongomallard-test',
+}
+
+connect(**conn_settings)
+
+def timeit(f, n=10000):
+ return min(repeat(f, repeat=3, number=n))/float(n)
+
+class BenchmarkTestCase(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_basic(self):
+ class Book(Document):
+ name = StringField()
+ pages = IntField()
+ tags = ListField(StringField())
+ is_published = BooleanField()
+
+ Book.drop_collection()
+
+ create_book = lambda: Book(name='Always be closing', pages=100, tags=['self-help', 'sales'], is_published=True)
+ print 'Doc initialization: %.3fus' % (timeit(create_book, 1000) * 10**6)
+
+ b = create_book()
+
+ print 'Doc getattr: %.3fus' % (timeit(lambda: b.name, 10000) * 10**6)
+
+ print 'Doc setattr: %.3fus' % (timeit(lambda: setattr(b, 'name', 'New name'), 10000) * 10**6)
+
+ print 'Doc to mongo: %.3fus' % (timeit(b.to_mongo, 1000) * 10**6)
+
+ def save_book():
+ b._mark_as_changed('name')
+ b._mark_as_changed('tags')
+ b.save()
+
+ save_book()
+ son = b.to_mongo()
+
+ print 'Load from SON: %.3fus' % (timeit(lambda: Book._from_son(son), 1000) * 10**6)
+
+ print 'Save to database: %.3fus' % (timeit(save_book, 100) * 10**6)
+
+ print 'Load from database: %.3fus' % (timeit(lambda: Book.objects[0], 100) * 10**6)
+
+ def test_embedded(self):
+ class Contact(EmbeddedDocument):
+ name = StringField()
+ title = StringField()
+ address = StringField()
+
+ class Company(Document):
+ name = StringField()
+ contacts = ListField(EmbeddedDocumentField(Contact))
+
+ Company.drop_collection()
+
+ def get_company():
+ return Company(
+ name='Elastic',
+ contacts=[
+ Contact(
+ name='Contact %d' % x,
+ title='CEO',
+ address='Address %d' % x,
+ )
+ for x in range(1000)]
+ )
+
+ def create_company():
+ c = get_company()
+ c.save()
+ c.delete()
+
+ print 'Save/delete big object to database: %.3fms' % (timeit(create_company, 10) * 10**3)
+
+ c = get_company().save()
+
+ print 'Serialize big object from database: %.3fms' % (timeit(c.to_mongo, 100) * 10**3)
+ print 'Load big object from database: %.3fms' % (timeit(lambda: Company.objects[0], 100) * 10**3)
+
+
+if __name__ == '__main__':
+ unittest.main()