Анализ Степени Ярусности (Одновременности) Процессов

Полезная программа не обязательно должна быть большой, верно? Пусть у нас есть процессы, для которых известно время их начала и окончания.

Таких в любой системе пруд пруди.

Такой же Хранилище журнала выполнения в MS SQL Reporting Server, SQL Server Profiler Trace, а также множество пользовательских метрик, которые есть у каждого.

Как осуществляются эти процессы? Спокойно, один за другим, хотят ли они идти все в ногу? Какова средняя и максимальная степень параллелизма этих процессов? Хотелось бы получить что-то вроде этого (процессы показаны черточками вверху):

Анализ степени ярусности (одновременности) процессов



Мы пишем на SQL?

Решение можно написать на SQL, но получается ПЕРЕКРЕСТНОЕ СОЕДИНЕНИЕ с выбором вариантов пересечения.

Сложность этого составляет O(n^2), а при 100 000 записей (10^10 вариантов) анализ становится практически невозможным.



Решение

Задачу можно решить на традиционном языке практически за линейное время, если данные отсортировать по столбцу времени начала процесса.

Если количество «слоев» не очень велико, то все решается за один проход. Прикрепленная программа получает на вход csv-файл (первая строка — заголовок), где должны быть столбцы с временем начала и окончания процесса в формате гггг/мм/дд чч:мм:сс (Формат ячеек -> Пользовательский) Файл должен быть отсортирован по дате начала процесса (если это не так, программа откажется его обрабатывать).

Запустим:

Анализ степени ярусности (одновременности) процессов

Второй и третий параметры — это номера столбцов с датой/временем начала и окончания процесса.

Нумерация начинается с нуля.

Файлы создаются: секунды.

csv - параллелизм для каждой секунды в обнаруженном диапазоне дат:

Анализ степени ярусности (одновременности) процессов

Далее рассчитываются агрегаты для более крупных периодов времени и для них рассчитываются максимальные и средние значения:

Анализ степени ярусности (одновременности) процессов

И вуаля, построим график:

Анализ степени ярусности (одновременности) процессов

А вот собственно код (еще раз извините, что маленькая программа, но для анализа многих вещей было очень полезно):

   

import os import sys import csv import numpy as np from datetime import datetime, timedelta if len(sys.argv) != 4: print ('Usage: python parr.py yourfile.csv colstartn colendn') print (' column numbers are counted from 0') print (' start and end columns must be in format yyyy/mm/dd hh:mm:ss') exit() csvfile = sys.argv[1] start = int(sys.argv[2]) fin = int(sys.argv[3]) prc = [] newprc = [] # check min and max first = True newest = datetime(1980,1,1) oldest = datetime(2030,1,1) prevs = newest with open(csvfile, 'rt', encoding='utf8') as f: reader = csv.reader(f) for r, row in enumerate(reader): if not first: s = datetime.strptime(row[start],"%Y/%m/%d %H:%M:%S") if s<prevs: print('Error: start column is not properly sorted') print(f' Value {s} < previous value {prevs}') exit(1) prevs = s e = datetime.strptime(row[fin],"%Y/%m/%d %H:%M:%S") if e>newest: newest=e if s<oldest: oldest=s first = False print ('Date range: ', oldest, ' - ', newest) seconds = int((newest-oldest).

total_seconds())+1 grid = np.array([], dtype=np.uint16) grid = np.zeros(seconds, dtype=np.uint16).

reshape(seconds) first = True ln = 0 with open(csvfile, 'rt', encoding='utf8') as f: reader = csv.reader(f) for r, row in enumerate(reader): if not first: s = datetime.strptime(row[start],"%Y/%m/%d %H:%M:%S") e = datetime.strptime(row[fin],"%Y/%m/%d %H:%M:%S") # add end time to list of processes prc.append(e) # check what processes stopped before s newprc = [i for i in prc if i >= s] prc = newprc secnum = int((s-oldest).

total_seconds()) duration = int((e-s).

total_seconds()) for k in range(duration): grid[secnum+k] += 1 ln += 1 first = False print(f'Analysis - {ln} points') ln = 0 with open('seconds.csv', 'w') as o: print('Time,processes', file=o) for s in range(seconds): print(f'{oldest+timedelta(seconds=s)},{grid[s]}', file=o) ln += 1 print(f'File seconds.csv - {ln} lines') aggregates = [60,300,900,1800,3600] aggfiles = ['minutes', 'minutes5', 'minutes15', 'minutes30', 'hours'] for aggname in aggfiles: demultiplier = aggregates.pop(0) ln = 0 with open(f'{aggname}.

csv', 'w') as o: print('Time,AvgRuns,MaxRuns', file=o) for m in range(seconds//demultiplier): sm = 0 mx = 0 for s in range(demultiplier): g = grid[m*demultiplier+s] sm += g if mx<g: mx=g print(f'{oldest+timedelta(seconds=m*demultiplier)},{sm/demultiplier},{mx}', file=o) ln += 1 print(f'File {aggname}.

csv - {ln} lines') exit()

Теги: #python #Администрирование сервера #Администрирование баз данных #Microsoft SQL Server #диаграммы #степень параллелизма
Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.