分析流程输出

时间:2014-06-16 23:12:19

标签: python cprofile

我有一个python脚本,用于分析Perforce服务器的输出。有了这个,我有两种不同的方法来输出在给定时间运行的进程。

1.启动流程缩进时的匹配流程缩进(P120会有119个缩进)

+P1 +P2 -P1 +P3 -P3 -P2

2.匹配流程缩进与运行的进程数

+P1 +P2 +P3 -P2 -P3 -P1

对于这两个函数,输入是我创建的过程对象列表。

类型1的代码:(慢)

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类代码:(快速)

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不是真的。虽然那是唯一会减慢我的脚本速度的东西吗?是否有其他人看到任何其他严重错误。如果您需要查看我在此脚本中调用的其他一些方法,请告诉我。

现在我确实在这两个函数上运行了一个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}

我试图理解这一点,看看它的速度在慢慢下降。我真正看到的唯一区别是该函数的第一次调用具有不同的全局。

有没有人能够使用更好的代码分析器?

如果您还有其他需要,请告诉我。

1 个答案:

答案 0 :(得分:0)

您可能想尝试构建一个&#34;标签字符串的查找表&#34;。

而不是:

output_string += ('\t' * indent_number)

尝试:

output_string += indent_string[ident_number]

显然,这需要一些逻辑才能将阵列预填充到一定水平,并且如果超出则继续动态构建。但如果这是你的问题,快速黑客应该会让你知道。