Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing performance benchmark comparison #29

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,43 +224,43 @@ You can run this benchmark on your machine with the following command:

python3 ./benchmarks/performance_comparison.py

Here are the results obtained on an Intel Core i5-7500U CPU (2.50GHz) with **Python 3.6.4**.
Here are the results obtained on an AMD 5950x with **Python 3.10.2**.


**Addict** 2.2.1::
**Addict** 2.4.0::

instantiate:-------- 271,132 ops per second.
get:---------------- 276,090 ops per second.
get through list:--- 293,773 ops per second.
set:---------------- 300,324 ops per second.
set through list:--- 282,149 ops per second.
instantiate:-------- 773,292 ops per second.
get:---------------- 1,197,604,715 ops per second.
get through list:--- 647,249,139 ops per second.
set:---------------- 130,434,783 ops per second.
set through list:--- 91,240,875 ops per second.


**Box** 3.4.2::
**Box** 6.0.1::

instantiate:--------- 4,093,439 ops per second.
get:----------------- 957,069 ops per second.
get through list:---- 164,013 ops per second.
set:----------------- 900,466 ops per second.
set through list:---- 165,522 ops per second.
instantiate:--------- 382,330 ops per second.
get:----------------- 57,853,629 ops per second.
get through list:---- 25,509,119 ops per second.
set:----------------- 29,902,815 ops per second.
set through list:---- 18,625,442 ops per second.


**Scalpl** latest::

instantiate:-------- 183,879,865 ops per second.
get:---------------- 14,941,355 ops per second.
get through list:--- 14,175,349 ops per second.
set:---------------- 11,320,968 ops per second.
set through list:--- 11,956,001 ops per second.
instantiate:-------- 367,421,940 ops per second.
get:---------------- 71,882,113 ops per second.
get through list:--- 37,406,484 ops per second.
set:---------------- 68,681,318 ops per second.
set through list:--- 40,647,652 ops per second.


**dict**::

instantiate:--------- 37,816,714 ops per second.
get:----------------- 84,317,032 ops per second.
get through list:---- 62,480,474 ops per second.
set:----------------- 146,484,375 ops per second.
set through list :--- 122,473,974 ops per second.
instantiate:--------- 612,870,255 ops per second.
get:----------------- 1,675,977,835 ops per second.
get through list:---- 746,268,647 ops per second.
set:----------------- 1,388,888,605 ops per second.
set through list :--- 798,934,707 ops per second.


As a conclusion and despite being an order of magniture slower than the built-in
Expand Down
136 changes: 75 additions & 61 deletions benchmarks/perfomance_comparison.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,61 @@
from copy import deepcopy
import json
from timeit import timeit
import unittest

from scalpl import Cut

from addict import Dict
from box import Box
import requests

PYTHON_REDDIT = {
"kind": "Listing",
"data": {
"modhash": "",
"dist": 27,
"children": [
{
"kind": "t3",
"data": {
"approved_at_utc": None, "subreddit": "Python",
"selftext": "Top Level comments must be **Job Opportunities.**\n\nPlease include **Location** or any other **Requirements** in your comment. If you require people to work on site in San Francisco, *you must note that in your post.* If you require an Engineering degree, *you must note that in your post*.\n\nPlease include as much information as possible.\n\nIf you are looking for jobs, send a PM to the poster.",
"author_fullname": "t2_628u", "saved": False,
"mod_reason_title": None, "gilded": 0, "clicked": False, "title": "r/Python Job Board",
"link_flair_richtext": [],
"subreddit_name_prefixed": "r/Python", "hidden": False, "pwls": 6, "link_flair_css_class": None,
"downs": 0, "hide_score": False, "name": "t3_cmq4jj",
"quarantine": False, "link_flair_text_color": "dark", "author_flair_background_color": "",
"subreddit_type": "public", "ups": 11, "total_awards_received": 0,
"media_embed": {}, "author_flair_template_id": None, "is_original_content": False,
"user_reports": [], "secure_media": None,
"is_reddit_media_domain": False, "is_meta": False, "category": None, "secure_media_embed": {},
"link_flair_text": None, "can_mod_post": False,
"score": 11, "approved_by": None, "thumbnail": "", "edited": False, "author_flair_css_class": "",
"author_flair_richtext": [], "gildings": {},
"content_categories": None, "is_self": True, "mod_note": None, "created": 1565124336.0,
"link_flair_type": "text", "wls": 6, "banned_by": None,
"author_flair_type": "text", "domain": "self.Python",
"allow_live_comments": False,
"selftext_html": "<!-- SC_OFF --><div class=\"md\"><p>Top Level comments must be <strong>Job Opportunities.</strong></p>\n\n<p>Please include <strong>Location</strong> or any other <strong>Requirements</strong> in your comment. If you require people to work on site in San Francisco, <em>you must note that in your post.</em> If you require an Engineering degree, <em>you must note that in your post</em>.</p>\n\n<p>Please include as much information as possible.</p>\n\n<p>If you are looking for jobs, send a PM to the poster.</p>\n</div><!-- SC_ON -->",
"likes": None, "suggested_sort": None, "banned_at_utc": None, "view_count": None, "archived": False,
"no_follow": False, "is_crosspostable": False, "pinned": False,
"over_18": False, "all_awardings": [], "media_only": False, "can_gild": False, "spoiler": False,
"locked": False, "author_flair_text": "reticulated",
"visited": False, "num_reports": None, "distinguished": None, "subreddit_id": "t5_2qh0y",
"mod_reason_by": None, "removal_reason": None, "link_flair_background_color": "",
"id": "cmq4jj", "is_robot_indexable": True, "report_reasons": None, "author": "aphoenix",
"num_crossposts": 0, "num_comments": 2, "send_replies": False, "whitelist_status": "all_ads",
"contest_mode": False, "mod_reports": [], "author_patreon_flair": False,
"author_flair_text_color": "dark",
"permalink": "/r/Python/comments/cmq4jj/rpython_job_board/", "parent_whitelist_status": "all_ads",
"stickied": True,
"url": "https://www.reddit.com/r/Python/comments/cmq4jj/rpython_job_board/",
"subreddit_subscribers": 399170, "created_utc": 1565095536.0,
"discussion_type": None, "media": None, "is_video": False
}
}
]
}
}


class TestDictPerformance(unittest.TestCase):
Expand All @@ -18,48 +66,15 @@ class TestDictPerformance(unittest.TestCase):

# We use a portion of the JSON dump of the Python Reddit page.

PYTHON_REDDIT = {
"kind": "Listing",
"data": {
"modhash": "",
"dist": 27,
"children": [
{
"kind": "t3",
"data": {
"approved_at_utc": None, "subreddit": "Python",
"selftext": "Top Level comments must be **Job Opportunities.**\n\nPlease include **Location** or any other **Requirements** in your comment. If you require people to work on site in San Francisco, *you must note that in your post.* If you require an Engineering degree, *you must note that in your post*.\n\nPlease include as much information as possible.\n\nIf you are looking for jobs, send a PM to the poster.",
"author_fullname": "t2_628u", "saved": False,
"mod_reason_title": None, "gilded": 0, "clicked": False, "title": "r/Python Job Board", "link_flair_richtext": [],
"subreddit_name_prefixed": "r/Python", "hidden": False, "pwls": 6, "link_flair_css_class": None, "downs": 0, "hide_score": False, "name": "t3_cmq4jj",
"quarantine": False, "link_flair_text_color": "dark", "author_flair_background_color": "", "subreddit_type": "public", "ups": 11, "total_awards_received": 0,
"media_embed": {}, "author_flair_template_id": None, "is_original_content": False, "user_reports": [], "secure_media": None,
"is_reddit_media_domain": False, "is_meta": False, "category": None, "secure_media_embed": {}, "link_flair_text": None, "can_mod_post": False,
"score": 11, "approved_by": None, "thumbnail": "", "edited": False, "author_flair_css_class": "", "author_flair_richtext": [], "gildings": {},
"content_categories": None, "is_self": True, "mod_note": None, "created": 1565124336.0, "link_flair_type": "text", "wls": 6, "banned_by": None,
"author_flair_type": "text", "domain": "self.Python",
"allow_live_comments": False,
"selftext_html": "<!-- SC_OFF --><div class=\"md\"><p>Top Level comments must be <strong>Job Opportunities.</strong></p>\n\n<p>Please include <strong>Location</strong> or any other <strong>Requirements</strong> in your comment. If you require people to work on site in San Francisco, <em>you must note that in your post.</em> If you require an Engineering degree, <em>you must note that in your post</em>.</p>\n\n<p>Please include as much information as possible.</p>\n\n<p>If you are looking for jobs, send a PM to the poster.</p>\n</div><!-- SC_ON -->",
"likes": None, "suggested_sort": None, "banned_at_utc": None, "view_count": None, "archived": False, "no_follow": False, "is_crosspostable": False, "pinned": False,
"over_18": False, "all_awardings": [], "media_only": False, "can_gild": False, "spoiler": False, "locked": False, "author_flair_text": "reticulated",
"visited": False, "num_reports": None, "distinguished": None, "subreddit_id": "t5_2qh0y", "mod_reason_by": None, "removal_reason": None, "link_flair_background_color": "",
"id": "cmq4jj", "is_robot_indexable": True, "report_reasons": None, "author": "aphoenix", "num_crossposts": 0, "num_comments": 2, "send_replies": False, "whitelist_status": "all_ads",
"contest_mode": False, "mod_reports": [], "author_patreon_flair": False, "author_flair_text_color": "dark",
"permalink": "/r/Python/comments/cmq4jj/rpython_job_board/", "parent_whitelist_status": "all_ads", "stickied": True,
"url": "https://www.reddit.com/r/Python/comments/cmq4jj/rpython_job_board/", "subreddit_subscribers": 399170, "created_utc": 1565095536.0,
"discussion_type": None, "media": None, "is_video": False
}
}
]
}
}


namespace = {
'Wrapper': dict
'Wrapper': dict,
'Built': dict(deepcopy(PYTHON_REDDIT))
}

def setUp(self):
self.data = deepcopy(self.PYTHON_REDDIT)
self.data = deepcopy(PYTHON_REDDIT)
self.namespace.update(self=self)

def execute(self, statement, method):
Expand All @@ -79,21 +94,21 @@ def test_init(self):
self.execute('Wrapper(self.data)', 'instantiate')

def test_getitem(self):
self.execute("Wrapper(self.data)['data']['modhash']", 'get')
self.execute("Built['data']['modhash']", 'get')

def test_getitem_through_list(self):
statement = (
"Wrapper(self.data)['data']['children'][0]['data']['author']"
"Built['data']['children'][0]['data']['author']"
)
self.execute(statement, 'get through list')

def test_setitem(self):
statement = "Wrapper(self.data)['data']['modhash'] = 'dunno'"
statement = "Built['data']['modhash'] = 'dunno'"
self.execute(statement, 'set')

def test_setitem_through_list(self):
statement = (
"Wrapper(self.data)['data']['children'][0]"
"Built['data']['children'][0]"
"['data']['author'] = 'Captain Obvious'"
)
self.execute(statement, 'set through list')
Expand All @@ -102,25 +117,26 @@ def test_setitem_through_list(self):
class TestCutPerformance(TestDictPerformance):

namespace = {
'Wrapper': Cut
'Wrapper': Cut,
'Built': Cut(deepcopy(PYTHON_REDDIT))
}

def test_getitem(self):
self.execute("Wrapper(self.data)['data.modhash']", 'get')
self.execute("Built['data.modhash']", 'get')

def test_getitem_through_list(self):
statement = (
"Wrapper(self.data)['data.children[0].data.author']"
"Built['data.children[0].data.author']"
)
self.execute(statement, 'get through list')

def test_setitem(self):
statement = "Wrapper(self.data)['data.modhash'] = 'dunno'"
statement = "Built['data.modhash'] = 'dunno'"
self.execute(statement, 'set')

def test_setitem_through_list(self):
statement = (
"Wrapper(self.data)['data.children[0]"
"Built['data.children[0]"
".data.author'] = 'Captain Obvious'"
)
self.execute(statement, 'set through list')
Expand All @@ -129,38 +145,36 @@ def test_setitem_through_list(self):
class TestBoxPerformance(TestDictPerformance):

namespace = {
'Wrapper': Box
'Wrapper': Box,
'Built': Box(deepcopy(PYTHON_REDDIT))
}

def test_getitem(self):
self.execute("Wrapper(self.data).data.modhash", 'get - 1st lookup')
self.execute("Wrapper(self.data).data.modhash", 'get - 2nd lookup')
self.execute("Built.data.modhash", 'get')

def test_getitem_through_list(self):
statement = (
"Wrapper(self.data).data.children[0].data.author"
"Built.data.children[0].data.author"
)
self.execute(statement, 'get through list - 1st lookup')
self.execute(statement, 'get through list - 2nd lookup')
self.execute(statement, 'get through list')

def test_setitem(self):
statement = "Wrapper(self.data).data.modhash = 'dunno'"
self.execute(statement, 'set - 1st lookup')
self.execute(statement, 'set - 2nd lookup')
statement = "Built.data.modhash = 'dunno'"
self.execute(statement, 'set')

def test_setitem_through_list(self):
statement = (
"Wrapper(self.data).data.children[0]"
"Built.data.children[0]"
".data.author = 'Captain Obvious'"
)
self.execute(statement, 'set through list - 1st lookup')
self.execute(statement, 'set through list - 2nd lookup')
self.execute(statement, 'set through list')


class TestAddictPerformance(TestDictPerformance):

namespace = {
'Wrapper': Dict
'Wrapper': Dict,
'Built': Dict(deepcopy(PYTHON_REDDIT))
}


Expand Down