@@ -57,17 +57,48 @@ def coerce_to_strict(const):
57
57
return const
58
58
59
59
60
+ def time_engine (engine , plotly_object ):
61
+ import time
62
+ # time in seconds
63
+ t_total = 0
64
+ n_total = 0
65
+
66
+ # Call function for at least total of 2 seconds and at least 10 times
67
+ n_min = 10
68
+ t_min = 1
69
+
70
+ while t_total < t_min or n_total < n_min :
71
+ t0 = time .perf_counter ()
72
+ _to_json_plotly (plotly_object , engine = engine )
73
+ t1 = time .perf_counter ()
74
+ n_total += 1
75
+ t_total += (t1 - t0 )
76
+
77
+ # return time in ms
78
+ return 1000 * t_total / n_total
79
+
80
+
60
81
def to_json_plotly (plotly_object , pretty = False , engine = None ):
82
+ if engine is not None :
83
+ return _to_json_plotly (plotly_object , pretty = pretty , engine = engine )
84
+
61
85
# instrucment _to_json_plotly by running it with all 3 engines and comparing results
62
- # before returning
86
+ # before returnin
87
+
88
+ import timeit
89
+ from IPython import get_ipython
90
+ ipython = get_ipython ()
63
91
orjson = get_module ("orjson" , should_load = True )
64
92
results = {}
93
+ timing = {}
65
94
result_str = None
66
- for engine in ["legacy " , "json " , "orjson " ]:
95
+ for engine in ["json " , "orjson " , "legacy " ]:
67
96
if orjson is None and engine == "orjson" :
68
97
continue
98
+
69
99
result_str = _to_json_plotly (plotly_object , pretty = pretty , engine = engine )
70
100
results [engine ] = from_json_plotly (result_str , engine = engine )
101
+ timing [engine ] = time_engine (engine , plotly_object )
71
102
72
103
# Check matches
73
104
if results ["legacy" ] != results ["json" ]:
@@ -91,6 +122,19 @@ def to_json_plotly(plotly_object, pretty=False, engine=None):
91
122
)
92
123
)
93
124
125
+ # write timing
126
+ import uuid
127
+ import pickle
128
+ import os
129
+ uid = str (uuid .uuid4 ())
130
+ with open ("json_timing.csv" .format (engine ), "at" ) as f :
131
+ f .write ("{}, {}, {}, {}, {}\n " .format (
132
+ timing ["legacy" ], timing ["json" ], timing ["orjson" ], len (result_str ), uid )
133
+ )
134
+ os .makedirs ("json_object" , exist_ok = True )
135
+ with open ("json_object/{uid}.pkl" .format (uid = uid ), "wb" ) as f :
136
+ pickle .dump (plotly_object , f )
137
+
94
138
return result_str
95
139
96
140
@@ -495,6 +539,20 @@ def clean_to_json_compatible(obj, **kwargs):
495
539
if isinstance (obj , (int , float , string_types )):
496
540
return obj
497
541
542
+ # Plotly
543
+ try :
544
+ obj = obj .to_plotly_json ()
545
+ except AttributeError :
546
+ pass
547
+
548
+ # And simple lists
549
+ if isinstance (obj , (list , tuple )):
550
+ # Must process list recursively even though it may be slow
551
+ return [clean_to_json_compatible (v , ** kwargs ) for v in obj ]
552
+ # Recurse into lists and dictionaries
553
+ if isinstance (obj , dict ):
554
+ return {k : clean_to_json_compatible (v , ** kwargs ) for k , v in obj .items ()}
555
+
498
556
# unpack kwargs
499
557
numpy_allowed = kwargs .get ("numpy_allowed" , False )
500
558
datetime_allowed = kwargs .get ("datetime_allowed" , False )
@@ -505,12 +563,6 @@ def clean_to_json_compatible(obj, **kwargs):
505
563
pd = modules ["pd" ]
506
564
image = modules ["image" ]
507
565
508
- # Plotly
509
- try :
510
- obj = obj .to_plotly_json ()
511
- except AttributeError :
512
- pass
513
-
514
566
# Sage
515
567
if sage_all is not None :
516
568
if obj in sage_all .RR :
@@ -531,7 +583,7 @@ def clean_to_json_compatible(obj, **kwargs):
531
583
elif obj .dtype .kind == "U" :
532
584
return obj .tolist ()
533
585
elif obj .dtype .kind == "O" :
534
- # Treat object array as a lists, continue processing
586
+ # Treat object array as plain list, allow recursive processing below
535
587
obj = obj .tolist ()
536
588
elif isinstance (obj , np .datetime64 ):
537
589
return str (obj )
@@ -588,12 +640,8 @@ def clean_to_json_compatible(obj, **kwargs):
588
640
if image is not None and isinstance (obj , image .Image ):
589
641
return ImageUriValidator .pil_image_to_uri (obj )
590
642
591
- # Recurse into lists and dictionaries
592
- if isinstance (obj , dict ):
593
- return {k : clean_to_json_compatible (v , ** kwargs ) for k , v in obj .items ()}
594
- elif isinstance (obj , (list , tuple )):
595
- if obj :
596
- # Must process list recursively even though it may be slow
597
- return [clean_to_json_compatible (v , ** kwargs ) for v in obj ]
643
+ if isinstance (obj , (list , tuple )) and obj :
644
+ # Must process list recursively even though it may be slow
645
+ return [clean_to_json_compatible (v , ** kwargs ) for v in obj ]
598
646
599
647
return obj
0 commit comments