From 555f370747550cb67cd62573b79c0098e3e638d8 Mon Sep 17 00:00:00 2001 From: KalenikAI Date: Thu, 14 Jan 2021 17:16:54 +0300 Subject: [PATCH] Lesson_6 --- task_1.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ task_2.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ task_3.py | 32 ++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 task_1.py create mode 100644 task_2.py create mode 100644 task_3.py diff --git a/task_1.py b/task_1.py new file mode 100644 index 00000000..f8bb2e6c --- /dev/null +++ b/task_1.py @@ -0,0 +1,73 @@ +""" +Задание 1. + +Выполните профилирование памяти в скриптах +Проанализировать результат и определить программы с +наиболее эффективным использованием памяти. + +Примечание: Для анализа возьмите любые 1-5 ваших разных скриптов!. +Сделать их разные реализации. + +Можно взять задачи с курса Основ +или с текущего курса Алгоритмов + +Результаты анализа вставьте в виде комментариев к коду. +Также укажите в комментариях версию Python и разрядность вашей ОС. + +ВНИМАНИЕ: ЗАДАНИЯ, В КОТОРЫХ БУДУТ ГОЛЫЕ ЦИФРЫ ЗАМЕРОВ (БЕЗ АНАЛИТИКИ) +БУДУТ ПРИНИМАТЬСЯ С ОЦЕНКОЙ УДОВЛЕТВОРИТЕЛЬНО + +Попытайтесь дополнительно свой декоратор используя ф-цию memory_usage из memory_profiler +С одновременным замером времени (timeit.default_timer())! +""" +import memory_profiler +import time + +# +def get_odd_1(value): + result = [] + for var in range(value): + if var % 2: + result.append(var) + +def get_odd_2(value): + return [var for var in range(value) if var % 2] + +def get_odd_3(value): + for num in range(value): + if num % 2: + yield num + +if __name__ == '__main__': + value = 10000000 + t1 = time.process_time() + m1 = memory_profiler.memory_usage() + get_odd_1(value) + t2 = time.process_time() + m2 = memory_profiler.memory_usage() + print(f"Выполнение get_odd_1 заняло {t2 - t1} сек and {m2[0] - m1[0]} Мб") + + t1 = time.process_time() + m1 = memory_profiler.memory_usage() + get_odd_2(value) + t2 = time.process_time() + m2 = memory_profiler.memory_usage() + print(f"Выполнение get_odd_2 заняло {t2 - t1} сек and {m2[0] - m1[0]} Мб") + + t1 = time.process_time() + m1 = memory_profiler.memory_usage() + mygenerator = get_odd_3(value) + for i in mygenerator: + i + t2 = time.process_time() + m2 = memory_profiler.memory_usage() + print(f"Выполнение get_odd_3 и цикла заняло {t2 - t1} сек and {m2[0] - m1[0]} Мб") + +""" +Выполнение get_odd_1 заняло 0.078125 сек and 1.33203125 Мб +Выполнение get_odd_2 заняло 0.046875 сек and 0.00390625 Мб +Выполнение get_odd_1 и цикла заняло 0.0625 сек and 0.0 Мб +С точки зренеия оптимальности времени выполнения генераторное выражение оптимально, однако с точки зрения использования памяти generator - имеет неоспоримые преимущества. +Как я понимаю генераторная (generator) функция выполняется долго из-за цикла, в котором получаются выходные значения. +Python 3.8.4 (tags/v3.8.4:dfa645a, Jul 13 2020, 16:46:45) [MSC v.1924 64 bit (AMD64)] +""" \ No newline at end of file diff --git a/task_2.py b/task_2.py new file mode 100644 index 00000000..ef7075d7 --- /dev/null +++ b/task_2.py @@ -0,0 +1,71 @@ +""" +Задание 2.* +Предложить еще какие-либо варианты (механизмы, библиотеки) для оптимизации памяти и +доказать! (наглядно, кодом) их эффективность (на примере профилировщика) +""" +from functools import total_ordering +import memory_profiler +from pympler import asizeof +from sys import getsizeof + +class Number_1: + def __init__(self, value): + self.value = value + + def __eq__(self, other): + return self.value == other + + def __lt__ (self, other): + return self.value < other + + def __le__ (self, other): + return self.value <= other + + def __gt__ (self, other): + return self.value > other + + def __ge__ (self, other): + return self.value >= other + +@total_ordering +class Number_2: + def __init__(self, value): + self.value = value + + def __eq__(self, other): + return self.value == other + + def __lt__ (self, other): + return self.value < other + + +if __name__ == '__main__': + + m1 = memory_profiler.memory_usage() + num1 = Number_1(5) + num2 = Number_1(3) + print(num1 == num2) + print(num1 < num2) + print(num1 <= num2) + print(num1 > num2) + print(num1 >= num2) + m2 = memory_profiler.memory_usage() + print(f"Работа с Number_1 {m2[0] - m1[0]} Мб") + print(asizeof.asizeof(Number_1)) + + m1 = memory_profiler.memory_usage() + num3 = Number_2(5) + num4 = Number_2(3) + print(num3 == num4) + print(num3 < num4) + print(num3 <= num4) + print(num3 > num4) + print(num3 >= num4) + m2 = memory_profiler.memory_usage() + print(f"Работа с Number_1 {m2[0] - m1[0]} Мб") + print(asizeof.asizeof(Number_1)) + +""" +Должно оптимизировать, но профилировщик показывает нули. + +""" \ No newline at end of file diff --git a/task_3.py b/task_3.py new file mode 100644 index 00000000..a561c364 --- /dev/null +++ b/task_3.py @@ -0,0 +1,32 @@ +""" +Задание 3 *. +Сделать профилировку для скриптов с рекурсией и сделать описание, +можно ли так профилировать и есть ли 'подводные камни' в профилировании? +Придумать как это решить! +Есть очень простое решение! +""" +import time + +def time_of_function(function): + def wrapped(*args): + start_time = time.perf_counter() + res = function(*args) + print(f'Execution time for {function} is {time.perf_counter() - start_time} sec') + return res + return wrapped + +@time_of_function +def reverse_digits(number): + rev = str(number % 10) + if number != 0: + return rev + reverse_digits(number // 10) + else: + return '' + + +print(reverse_digits(123)) +print + +""" +Как решить проблему с многократными вызовами декоратора не нашел. +""" \ No newline at end of file