Как сократить время выполнения в моем коде python?

#python #numpy #runtime #nested-for-loop

#питон #тупица #время выполнения #вложенный для цикла

Вопрос:

В настоящее время я работаю над проектом, который требует от меня запуска полной базы кода python. В исследовательских целях мне нужно запустить код как можно быстрее. Тем не менее, я довольно новичок в программировании и понятия не имею, как сократить время выполнения. Поэтому я надеюсь, что кто-нибудь сможет мне в этом помочь. Буду признателен за любой совет. Вот часть моей базы кода, в которой использовалось много вложенных циклов for, поэтому это может значительно увеличить время выполнения.

 def a_j(r, a, A): # the Claussius-Mossotti factor, determined by a symmetric (3 × 3) matrix such that (A_i)^T = A_i  alph = np.array([[0,0,0],[0,0,0],[0,0,0]],complex)  for i in range(3):  for j in range(3):  alph[i,j] = (r * a * A[i,j])  return alph   def W_ext(x, k, rho, alpha, A): # particle–particle interaction term  n = x.shape[0] # the number of x vextors   result = np.zeros([3*n,3*n],complex)  u = np.zeros((n, 3)) # u = x - x'     for i in range(n):  for j in range(n):  if i != j:  u[i] = x[i] - x[j]  block_result = a_j(rho[i], alpha, A) * G((u[i]), k) * a_j(rho[j], alpha, A)   for m in range(3):  for l in range(3):  result[3*i   m, 3*j   l] = block_result[m,l]  return result.imag    def A_ext(rho, a, A): # single-particle term  n = rho.shape[0]  result = np.zeros([3*n,3*n],complex)    for i in range(n):  for j in range(n):  if i == j:  block_result = a_j(rho[i], a, A).imag  for m in range(3):  for l in range(3):  result[3*i   m, 3*j   l] = block_result[m,l]  return result # (3 x 3) matrix    def P_ext(e, A, W, omega):  eT = np.matrix.getH(e)  mm1 = np.matmul(A, e)  mm2 = np.matmul(W, e)  extinction = (np.dot(eT, mm1)   np.dot(eT, mm2)) * (omega/2.0)  return extinction    #ABSORPTION    def W_abs(x, k, rho, alpha, A, chi): # particle–particle interaction term  n = x.shape[0]   result = np.zeros([3*n,3*n],complex)  u = np.zeros((n, 3))     for i in range(n):  for j in range(n):  if i != j:  u[i] = x[i] - x[j]  block_result = np.matrix.getH(a_j(rho[i], alpha, A)) * (1.0 / np.conjugate(chi)).imag * a_j(rho[i], alpha, A) * G((u[i]), k) * a_j(rho[j], alpha, A)   for m in range(3):  for l in range(3):  result[3*i   m, 3*j   l] = block_result[m,l]     return 2.0 * result.real # (3 x 3) matrix   def A_abs(rho, a, A, chi): # single-particle term  n = rho.shape[0]  result = np.zeros([3*n,3*n],complex)    for i in range(n):  for j in range(n):  if i == j:  block_result = np.matrix.getH(a_j(rho[i], a, A)) * (1.0 / np.conjugate(chi)).imag * a_j(rho[i], a, A)  for m in range(3):  for l in range(3):  result[3*i   m, 3*j   l] = block_result[m,l]  return result # (3 x 3) matrix  

Комментарии:

1. что это за соглашение об именовании О. О.

2. Один пример: если у вас есть вложенный цикл над i и j, с «если(i==j)» в теле, просто отбросьте внутренний цикл и используйте «i» там, где в данный момент отображается «j». Аналогично в некоторых других def.

3. Что такое a_j ? вложенные for циклы всегда будут увеличивать время выполнения. Первые 2 цикла сами по себе учитывают O(n^2) временную сложность. Добавьте к этому любую стоимость звонка a_j .

4. Python — это не тот путь, по которому нужно идти, если вы хотите действительно хорошей производительности, особенно для циклов, которые имеют много накладных расходов по сравнению с чем-то, созданным с помощью собственного кода. Для этого вам нужно будет использовать библиотеки Python, которые являются скомпилированными двоичными файлами, или создать свою собственную библиотеку, или использовать Cython или что-то подобное, чтобы объединить высокопроизводительный код C с гибкостью Python.

5. Я не numpy эксперт, но я думаю, что большая часть смысла использования np.array , как вы пытаетесь сделать, заключается в том, чтобы взять типы операций, которые вы выполняете в for циклах Python, и поместить их в numpy вызовы, которые выполняются как скомпилированный C, а не в интерпретаторе Python. Я предлагаю провести некоторое время с документами numpy, чтобы посмотреть, есть ли функции, которые могли бы выполнять эквивалент того, что вы сейчас делаете в своем собственном коде.