|
1 | 1 | """ Basic utility functions. """
|
2 | 2 |
|
3 |
| -import sys, daiquiri |
| 3 | +import sys |
| 4 | +import daiquiri |
4 | 5 |
|
5 | 6 | from flask import session
|
6 | 7 | from flask_login import current_user
|
7 | 8 |
|
| 9 | +import psutil |
| 10 | +from pympler import muppy, summary |
| 11 | + |
| 12 | +from webapp.home.utils.hidden_buttons import is_hidden_button, handle_hidden_buttons |
| 13 | + |
8 | 14 | from metapype.model.node import Node
|
9 | 15 |
|
10 |
| -RELEASE_NUMBER = '2023.11.29' |
| 16 | +RELEASE_NUMBER = '2024.01.03' |
11 | 17 |
|
12 | 18 |
|
13 | 19 | def extract_caller_module_name():
|
@@ -68,8 +74,106 @@ def log_available_memory():
|
68 | 74 | """
|
69 | 75 | Log the available system memory.
|
70 | 76 | """
|
71 |
| - import psutil |
72 | 77 | available_memory = psutil.virtual_memory().available / 1024 / 1024
|
73 | 78 | process_usage = psutil.Process().memory_info().rss / 1024 / 1024
|
74 | 79 | log_info(f"Memory usage: available system memory:{available_memory:.1f} MB process usage:{process_usage:.1f} MB")
|
75 | 80 |
|
| 81 | + |
| 82 | +# def profile_and_save(func, *args, **kwargs): |
| 83 | +# # Profile the function and get memory usage |
| 84 | +# mem_usage = memory_usage((func, args, kwargs)) |
| 85 | +# |
| 86 | +# # Save the results to a file |
| 87 | +# with open('memory_profile.txt', 'a') as file: |
| 88 | +# file.write("Memory usage (in MB):\n") |
| 89 | +# for point in mem_usage: |
| 90 | +# file.write(f"{point}\n") |
| 91 | +# |
| 92 | +# |
| 93 | +# def profile_and_save_with_return(func, *args, **kwargs): |
| 94 | +# # Function to wrap the original function and capture its return value |
| 95 | +# def wrapper(): |
| 96 | +# return func(*args, **kwargs) |
| 97 | +# |
| 98 | +# # Profile the memory usage of the wrapper function |
| 99 | +# mem_usage, retval = memory_usage((wrapper,), retval=True, max_usage=True) |
| 100 | +# |
| 101 | +# # Save the memory usage data to a file |
| 102 | +# with open('memory_profile.txt', 'w') as file: |
| 103 | +# file.write("Memory usage (in MB):\n") |
| 104 | +# file.write(f"{mem_usage}\n") |
| 105 | +# |
| 106 | +# # Return the original function's return value |
| 107 | +# return retval |
| 108 | + |
| 109 | + |
| 110 | +def log_profile_details(all_objects_before, all_objects_after): |
| 111 | + from pympler import asizeof |
| 112 | + |
| 113 | + ids_before = {id(obj) for obj in all_objects_before} |
| 114 | + ids_after = {id(obj) for obj in all_objects_after} |
| 115 | + |
| 116 | + # Find new object IDs |
| 117 | + new_ids = ids_after - ids_before |
| 118 | + |
| 119 | + # Retrieve new objects |
| 120 | + new_objects = [obj for obj in all_objects_after if id(obj) in new_ids] |
| 121 | + |
| 122 | + # Optionally, filter by type (e.g., list) |
| 123 | + new_lists = [obj for obj in new_objects if isinstance(obj, list)] |
| 124 | + |
| 125 | + # Sort by size and save the results to a file |
| 126 | + # original_stdout = sys.stdout |
| 127 | + with open('memory_profile.txt', 'a') as file: |
| 128 | + sys.stdout = file |
| 129 | + file.write("*********** Details ***********\n") |
| 130 | + obj = new_lists[0] |
| 131 | + print(f"List size: {asizeof.asizeof(obj)} bytes, Length: {len(obj)}, Example content: {str(obj[:10])}...") |
| 132 | + |
| 133 | + for obj in sorted(new_lists, key=lambda x: asizeof.asizeof(x), reverse=True)[:5]: |
| 134 | + print(f"List size: {asizeof.asizeof(obj)} bytes, Length: {len(obj)}, Example content: {str(obj[:10])}...") |
| 135 | + file.write("*********** End of details ***********\n") |
| 136 | + # sys.stdout = original_stdout |
| 137 | + |
| 138 | + |
| 139 | +def profile_and_save(func, *args, **kwargs): |
| 140 | + # Profile the function and get memory usage |
| 141 | + |
| 142 | + # Start tracking memory |
| 143 | + all_objects_before = muppy.get_objects() |
| 144 | + summary_1 = summary.summarize(all_objects_before) |
| 145 | + |
| 146 | + # Execute the function |
| 147 | + retval = func(*args, **kwargs) |
| 148 | + |
| 149 | + # Check memory after the function execution |
| 150 | + all_objects_after = muppy.get_objects() |
| 151 | + summary_2 = summary.summarize(all_objects_after) |
| 152 | + |
| 153 | + # Compare before and after snapshots |
| 154 | + diff = summary.get_diff(summary_1, summary_2) |
| 155 | + |
| 156 | + original_stdout = sys.stdout |
| 157 | + |
| 158 | + try: |
| 159 | + # Save the results to a file |
| 160 | + with open('memory_profile.txt', 'a') as file: |
| 161 | + sys.stdout = file |
| 162 | + file.write(f"*********** Summary of memory usage: {func_name} ***********\n") |
| 163 | + summary.print_(diff) |
| 164 | + file.write("*********** End of summary ***********\n") |
| 165 | + |
| 166 | + # Log details about the new objects |
| 167 | + # log_profile_details(all_objects_before, all_objects_after) |
| 168 | + except Exception as e: |
| 169 | + log_error(f"Error writing memory profile: {e}") |
| 170 | + raise |
| 171 | + finally: |
| 172 | + sys.stdout = original_stdout |
| 173 | + |
| 174 | + return retval |
| 175 | + |
| 176 | + |
| 177 | + |
| 178 | + |
| 179 | + |
0 commit comments