Perforce サーバーの出力を分析する python スクリプトがあります。これにより、特定の時間にどのプロセスが実行されているかを出力する 2 つの異なる方法があります。
1. プロセス インデントとプロセス インデントの開始を一致させる (P120 には 119 インデントがあります)
+P1
+P2
-P1
+P3
-P3
-P2
2.プロセスのインデントと実行中のプロセスの数を一致させる
+P1
+P2
+P3
-P2
-P3
-P1
これらの関数の両方の入力は、作成したプロセス オブジェクトのリストです。
タイプ 1 のコード: (SLOW)
def visual_output_match(processes):
output_string = ""
process_number = 1
indent_number = 0
running_processes = []
# Go through each process
for process in processes:
# Assign a process number to the new process that is about to start
process.set_process_number(process_number)
# This will append the process onto a list of processes that are currently running
running_processes.append(process)
# Get a list of processes that have ended before the new process started
ending_processes = check_ended_processes(running_processes, process)
# Delete the processes that have ended from the running_processes list
running_processes = remove_running_processes(running_processes, ending_processes)
# Print all the processes that finished before the new process began
for p in ending_processes:
# Tabs over the correct amount depending on how many processes are running
indent_number = p.get_process_number() - 1
output_string += ('\t' * indent_number)
output_string += ("-P" + str(p.get_process_number()) + " " + p.short_srting_summary_end() + '\n')
# Tabs over the correct amount depending on how many processes are running
indent_number = process.get_process_number() - 1
output_string += ('\t' * indent_number)
output_string += ("+P" + str(process.get_process_number()) + " " + process.short_srting_summary_start() + '\n')
process_number += 1
return output_string`
タイプ 2 のコード: (FAST)
def visual_output_not_match(processes):
output_string = ""
number_tabs = 0
process_number = 1
running_processes = []
# Go through each process
for process in processes:
# Assign a process number to the new process that is about to start
process.set_process_number(process_number)
# This will append the process onto a list of processes that are currently running
running_processes.append(process)
# Get a list of processes that have ended before the new process started
ending_processes = check_ended_processes(running_processes, process)
# Delete the processes that have ended from the running_processes list
running_processes = remove_running_processes(running_processes, ending_processes)
# Print all the processes that finished before the new process began
for p in ending_processes:
number_tabs -= 1
# Tabs over the correct amount depending on how many processes are running
output_string += ('\t' * number_tabs)
output_string += ("-P" + str(p.get_process_number()) + " " + p.short_srting_summary_end() + '\n')
# Tabs over the correct amount depending on how many processes are running
output_string += ("\t" * number_tabs)
output_string += ("+P" + str(process.get_process_number()) + " " + process.short_srting_summary_start() + '\n')
number_tabs += 1
process_number += 1
return output_string
正確な数のプロセスでは、最初のタイプは 11 分以上かかりますが、他のタイプは約 1 秒しかかかりません。タイプ 1 で 11,000 のプロセスがある場合、ある時点で特定の行に 11,000 のタブがあり、タイプ 2 ではそうではないことに気付きました。それが私のスクリプトを遅くしている唯一のものでしょうか? 他の誰かが他の重大なエラーを見ますか? このスクリプトで私が呼び出すその他のメソッドを確認する必要がある場合はお知らせください。
これら 2 つの関数で cProfiler を実行したところ、次のようになりました。
1: (遅い)
3381490 function calls in 681.195 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 679.175 679.175 681.182 681.182 visual_output.py:107(visual_output_match)
13706 0.568 0.000 0.769 0.000 visual_output.py:147(check_ended_processes)
13706 0.404 0.000 0.657 0.000 visual_output.py:162(remove_running_processes)
13706 0.258 0.000 0.264 0.000 server_info.py:398(short_srting_summary_start)
13702 0.257 0.000 0.264 0.000 server_info.py:402(short_srting_summary_end)
787125 0.206 0.000 0.206 0.000 server_info.py:67(__eq__)
800837 0.118 0.000 0.118 0.000 server_info.py:267(get_datetime_end)
800837 0.080 0.000 0.080 0.000 server_info.py:264(get_datetime_start)
800828 0.038 0.000 0.038 0.000 {len}
54816 0.028 0.000 0.028 0.000 server_info.py:308(get_process_number)
13706 0.018 0.000 0.018 0.000 server_info.py:406(set_process_number)
1 0.013 0.013 681.195 681.195 <string>:1(<module>)
27408 0.013 0.000 0.013 0.000 {method 'time' of 'datetime.datetime' objects}
27408 0.011 0.000 0.011 0.000 {method 'append' of 'list' objects}
13702 0.010 0.000 0.010 0.000 {method 'pop' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
2: (高速)
3354269 function calls (3354219 primitive calls) in 1.981 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.688 0.688 1.981 1.981 visual_output.py:67(visual_output_not_match)
13706 0.407 0.000 0.563 0.000 visual_output.py:147(check_ended_processes)
13706 0.375 0.000 0.603 0.000 visual_output.py:162(remove_running_processes)
787125 0.189 0.000 0.189 0.000 server_info.py:67(__eq__)
800837 0.079 0.000 0.079 0.000 server_info.py:267(get_datetime_end)
800837 0.075 0.000 0.075 0.000 server_info.py:264(get_datetime_start)
13706 0.059 0.000 0.061 0.000 server_info.py:398(short_srting_summary_start)
13702 0.053 0.000 0.055 0.000 server_info.py:402(short_srting_summary_end)
800850 0.035 0.000 0.035 0.000 {len}
13706 0.005 0.000 0.005 0.000 server_info.py:406(set_process_number)
27408 0.005 0.000 0.005 0.000 server_info.py:308(get_process_number)
13702 0.004 0.000 0.004 0.000 {method 'pop' of 'list' objects}
27434 0.003 0.000 0.003 0.000 {method 'append' of 'list' objects}
27408 0.003 0.000 0.003 0.000 {method 'time' of 'datetime.datetime' objects}
1 0.000 0.000 1.981 1.981 <string>:1(<module>)
2 0.000 0.000 0.000 0.000 {method 'send' of '_socket.socket' objects}
24/2 0.000 0.000 0.000 0.000 brine.py:202(_dump)
12/2 0.000 0.000 0.000 0.000 brine.py:179(_dump_tuple)
10 0.000 0.000 0.000 0.000 brine.py:106(_dump_int)
10/2 0.000 0.000 0.000 0.000 brine.py:360(dumpable)
2 0.000 0.000 0.000 0.000 protocol.py:220(_send)
2 0.000 0.000 0.000 0.000 protocol.py:227(_send_request)
2 0.000 0.000 0.000 0.000 channel.py:56(send)
2 0.000 0.000 0.000 0.000 <string>:531(write)
2 0.000 0.000 0.000 0.000 stream.py:173(write)
2 0.000 0.000 0.000 0.000 brine.py:332(dump)
14/8 0.000 0.000 0.000 0.000 brine.py:369(<genexpr>)
5 0.000 0.000 0.000 0.000 {method 'pack' of 'Struct' objects}
2 0.000 0.000 0.000 0.000 protocol.py:438(_async_request)
2 0.000 0.000 0.000 0.000 brine.py:150(_dump_str)
6/2 0.000 0.000 0.000 0.000 {all}
2 0.000 0.000 0.000 0.000 protocol.py:241(_box)
24 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects}
2 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects}
2 0.000 0.000 0.000 0.000 brine.py:173(_dump_long)
2 0.000 0.000 0.000 0.000 {method 'acquire' of 'thread.lock' objects}
2 0.000 0.000 0.000 0.000 {next}
4 0.000 0.000 0.000 0.000 compat.py:17(BYTES_LITERAL)
2 0.000 0.000 0.000 0.000 {method 'release' of 'thread.lock' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
私はこれを理解して、どこが遅くなっているのかを確認しようとしています。私が実際に目にする唯一の違いは、関数の最初の呼び出しの totime が異なることです。
私が使用できるより優れたコード アナライザーを持っている人はいますか?
他に必要なものがあれば教えてください。