<jupyter_start><jupyter_text>IntroThis notebook analyses the `checkIsType` method calls for the `http-ballerina-tests` test suite. The Types that are passed and the time taken to execute have been logged to CSV and the analysis can be found here. In order to measure the execution time, the `checkIsType` function was modified to run 10,000 times for every call. The hope was that this would reduce the noise associated with measuring small durations. However; we still notices that multiple calls of the same type checks can be differ by an order of maginitude. Thus, execution times of the same order of magnitude will be considered to be comparable.  Data Processing<jupyter_code>import csv
from tabulate import tabulate
def get_key(vals: list)-> str:
    return vals[0]+" / "+vals[1]

# Format and print float values
def print_f(dict, key: str)-> str:
    return f"{dict[key]:,.2f}"

# Format and print integer values
def print_i(dict, key: str)-> str:
    return f"{dict[key]:,d}"
count = 0
dict_count = {}
dict_total_time = {}
dict_time = {}

with open('./test-10000-full.csv', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        count += 1
        key = get_key(row[:2])
        if key in dict_count:
            dict_count[key] = dict_count[key] + 1
            dict_total_time[key] = dict_total_time[key] + int(row[2])
        else:
            dict_count[key] = 1
            dict_total_time[key] = int(row[2])

for key in dict_count:
    dict_time[key] = int(dict_total_time[key] / dict_count[key])

dict_count_sorted = sorted(dict_count.items(), key=lambda item: item[1],reverse=True)
dict_total_time_sorted = sorted(dict_total_time.items(), key=lambda item: item[1],reverse=True)
dict_time_sorted = sorted(dict_time.items(), key=lambda item: item[1],reverse=True)
print("Numeber of entires: ",count)
print("Numeber of unique entires: ",len(dict_count))<jupyter_output>Numeber of entires:  32951
Numeber of unique entires:  119<jupyter_text>Visualization<jupyter_code>show_amount = 30
print("Top %s common:"%show_amount)
print(tabulate(dict_count_sorted[:show_amount], headers=['Type', 'Number of occurrences'], tablefmt='orgtbl'))<jupyter_output>Top 30 common:
| Type                                                |   Number of occurrences |
|-----------------------------------------------------+-------------------------|
| int / int                                           |                    3582 |
| string / string                                     |                    2809 |
| boolean / boolean                                   |                    2653 |
| map / any                                           |                    1252 |
| float / float                                       |                    1217 |
| string / $anonType$_148|$anonType$_149              |                    1021 |
| http:ClientConfiguration / http:ClientConfiguration |                     985 |
| string / $anonType$_148                             |                     881 |
| http:CacheConfig / http:CacheConfig                 |                     830 |
| () / http:ClientSecureSocket|()                     |                     751 |
|[...]<jupyter_text>observations * Primitive type comparisions are very commom* Null checking of Object types are common* Object type checking is common<jupyter_code>print("Top %s cumulative time:"%show_amount)
print(tabulate(dict_total_time_sorted[:show_amount], headers=['Type', 'Total time (ns)'], tablefmt='orgtbl'))
print_i(dict_count,'http:HttpCachingClient / http:HttpClient')<jupyter_output><empty_output><jupyter_text>Observations* Type checking of object types that are similar is taking up (`http:HttpCachingClient / http:HttpClient` `http:CircuitBreakerClient / http:HttpClient` and `http:RedirectClient / http:HttpClient`) most of the processing time* This makes sense because the `checkIsType` logic has been written to fail fast for dissimilar types. Object types that are similar have to go through the longest execution paths.<jupyter_code>print("Top %s time:"%show_amount)
print(tabulate(dict_time_sorted[:show_amount], headers=['Type', 'Single execution time (ns)'], tablefmt='orgtbl'))
print_i(dict_count,'error / error')
dict_time_sorted[-10:]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11810102899906455, 'fraction_numerical': 0.019176800748362956, 'mean_word_length': 2.636904761904762, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '89349', 'license': 'Apache-2.0', 'n_tokens_mistral': 1249, 'n_tokens_neox': 1168, 'n_words': 354, 'path': 'checkIsType/checkIsType_analysis.ipynb', 'repo_name': 'ruvi-d/ballerina-perf-analysis', 'size': '4276'}