2015-08-13 3 views
-1

Я заметил, что моя программа слишком медленная, когда я делаю этот цикл, факт в том, что N является большим числом (1000000).Как оптимизировать цикл с большим числом

start=time.time() 
    ipf = 0 
    idx = 2 
    for iang in xrange(0, N): 
     z = np.float64(iang+1)/np.float64(N) 
     while scum[ipf+1]<z: 
      ipf += 1 

     phase_H[idx*5*N+iang*5+0] = np.float32(phase.phase[ipf, 1]) 
     phase_H[idx*5*N+iang*5+1] = np.float32(phase.phase[ipf, 0]) 
     phase_H[idx*5*N+iang*5+2] = np.float32(phase.phase[ipf, 2]) 
     phase_H[idx*5*N+iang*5+3] = np.float32(0) 
    print time.time() - start 

Этот код длится около 9 секунд. Есть ли способ сделать это быстрее?

+0

Попробуйте прочитать этот учебник и применить его http://www.bogotobogo.com/python/python_fncs_map_filter_reduce.php – Stiffo

+2

Можете ли вы добавить больше кода? Что такое 'scum'? – Cyphase

+0

Что такое 'scum',' phase_H', 'phase.phase'? Списки или np массивы? Какой размер (массив формы, если массив)? Что такое 'dtype' if array? – hpaulj

ответ

0

Означает, что внешний for цикл работает N раз, а внутренний цикл while пробегает все N элементов только один раз. Которая, я думаю, делает общую сложность O (2n), которая равна O (n)

Основная стоимость может быть в преобразовании в float numpy, некоторые из которых вы можете вытащить за пределы цикла for.

Из того, что при условии, я хотел бы предложить следующие изменения:

  1. преобразования Do вне для цикла

    converted_N = np.float64(N) 
    for iang in xrange(0, N): 
         z = np.float64(iang+1)/converted_N 
    
  2. брикетирования расчета индекса раз и увеличивающимся это вместо вычисления его каждый раз,

    base_index = idx*5*N+iang*5 
    phase_H[base_index] = np.float32(phase.phase[ipf, 1]) 
    phase_H[base_index+1] = np.float32(phase.phase[ipf, 0]) 
    phase_H[base_index+2] = np.float32(phase.phase[ipf, 2]) 
    

Вы также можете уменьшить это, перемещая idx*5 вне цикла while.

Это уменьшит количество умножений, однако их можно считать постоянным.

Без дополнительной информации о scum сравнительный тест не может быть запущен.

+0

hi @RMcG, спасибо за код, он остается медленным, я постараюсь поместить этот код в fortran и использовать f2py – axeldal

+0

@axeldal да, к сожалению, изменения на самом деле не сильно уменьшают сложность и, вероятно, будут незначительными. Удачи – RMcG

+0

Этот внутренний цикл на 'scum' просто пропускает некоторые значения - он просто продвигает индекс' ipf' по значениям, которые не имеют значения. Я не вижу смысла обматывать значения в 'np.float32'. Я никогда не делаю этого в коде «numpy». – hpaulj

Смежные вопросы