Skip to content

Commit 7882a62

Browse files
committed
�Speed up of compare_values and has_value methods by several orders of magnitude.
1 parent aa62815 commit 7882a62

File tree

1 file changed

+35
-28
lines changed

1 file changed

+35
-28
lines changed

lib/pyld/jsonld.py

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,6 @@ def to_rdf(self, input_, options):
11411141
issuer = IdentifierIssuer('_:b')
11421142
node_map = {'@default': {}}
11431143
self._create_node_map(expanded, node_map, '@default', issuer)
1144-
11451144
# output RDF dataset
11461145
dataset = {}
11471146
for graph_name, graph in sorted(node_map.items()):
@@ -1253,15 +1252,21 @@ def has_value(subject, property, value):
12531252
"""
12541253
if JsonLdProcessor.has_property(subject, property):
12551254
val = subject[property]
1256-
is_list = _is_list(val)
1257-
if _is_array(val) or is_list:
1258-
if is_list:
1259-
val = val['@list']
1255+
# Avoid double checking if val is a list.
1256+
# If val is a list, then we treat is as an array (i.e. if value occurs in the list, has_value returns true)
1257+
# TODO: is this desirable behavior?
1258+
if _is_list(val):
1259+
val = val['@list']
1260+
1261+
if _is_array(val):
12601262
for v in val:
1261-
if JsonLdProcessor.compare_values(value, v):
1262-
return True
1263+
# Avoid in depth comparison if the types are not the same
1264+
if type(v) == type(value):
1265+
return JsonLdProcessor.compare_values(value, v)
12631266
# avoid matching the set of values with an array value parameter
1264-
elif not _is_array(value):
1267+
# TODO: this means that if `value` is an array, there will be no comparison at all and we default to False
1268+
# is this desirable behavior?
1269+
elif not _is_array(value) and type(val) == type(value):
12651270
return JsonLdProcessor.compare_values(value, val)
12661271
return False
12671272

@@ -1374,31 +1379,33 @@ def compare_values(v1, v2):
13741379
13751380
:return: True if v1 and v2 are considered equal, False if not.
13761381
"""
1377-
# 1. equal primitives
1378-
if not _is_object(v1) and not _is_object(v2) and v1 == v2:
1379-
type1 = type(v1)
1380-
type2 = type(v2)
1381-
if type1 == bool or type2 == bool:
1382-
return type1 == type2
1383-
return True
13841382

1385-
# 2. equal @values
1386-
if (_is_value(v1) and _is_value(v2) and
1387-
v1['@value'] == v2['@value'] and
1388-
v1.get('@type') == v2.get('@type') and
1389-
v1.get('@language') == v2.get('@language') and
1390-
v1.get('@index') == v2.get('@index')):
1391-
type1 = type(v1['@value'])
1392-
type2 = type(v2['@value'])
1393-
if type1 == bool or type2 == bool:
1394-
return type1 == type2
1383+
# 1. equal primitives (= equal anything)
1384+
# This should just be equality...
1385+
# The previous version also returned true if one of the value types was bool and they were equal
1386+
# but they should only be equal if the types correspond as well.
1387+
# If they are both objects and they are equal in all respects, then they *are* equal (even if they are not primitives)
1388+
if v1 == v2:
13951389
return True
13961390

13971391
# 3. equal @ids
1398-
if (_is_object(v1) and '@id' in v1 and
1399-
_is_object(v2) and '@id' in v2):
1400-
return v1['@id'] == v2['@id']
1392+
# equal @ids only compares on one key, and is therefore preferred to do
1393+
# so let's do that first, and then only if there's a key error (i.e. no '@id'), we assume it's a value comparison.
1394+
try:
1395+
# If v1 and v2 have the same @id, they are the same
1396+
v1['@id'] == v2['@id']
1397+
except KeyError:
1398+
# if key error, then it is indeed a dict, but a literal value, not an object.
1399+
try:
1400+
return v1['@value'] == v2['@value'] and v1.get('@type') == v2.get('@type') and v1.get('@language') == v2.get('@language') and v1.get('@index') == v2.get('@index')
1401+
except:
1402+
# It is a dictionary, but a regular JSON one, not a JSON-LD dictionary
1403+
return False
1404+
except:
1405+
# one of v1 and v2 is not a dictionary
1406+
return False
14011407

1408+
# The two values are not the same.
14021409
return False
14031410

14041411
@staticmethod

0 commit comments

Comments
 (0)