2015-03-22 4 views
0

Вот какой код, который я написал для создания скользящего процентиля, оцененного в каждой строке массива. Этот код работает отлично, но он МЕДЛЕННЫЙ! Для запуска 8000 строк требуется 10 секунд, а мой компьютер не медленный. Кто-нибудь знает, как сделать этот запуск быстрее? Предостережения (все эти вычисления должны быть в памяти, поэтому ссылки на диапазон не допускаются). Я запустил формулу процентили как проверку с фиксированной точки, перетащил ее и быстрее, чем за одни и те же данные. Какие-нибудь советы?Как сделать скользящий процентиль оценен от начала до каждого элемента (через конец) в массиве

Большое вам спасибо! :)

Dim Current_MACD_Percentile() As Double 

    ReDim Preserve Current_MACD_Percentile(1 To UBound(MoveAvg5, 1), 1 To 1) 


      Dim Current_MACD_Percentile_Arr() As Double 
      Dim Current_MACD_Percentile_Elm_Arr As Variant 

        For x = 1 To UBound(MoveAvg5) 

          For w = 1 To x 
          ReDim Preserve Current_MACD_Percentile_Arr(1 To 1, 1 To x) 
          Current_MACD_Percentile_Arr(1, x) = MACD_SD_Pct(x, 1) 
          Next w 

        With Application.WorksheetFunction 
        Current_MACD_Percentile(x, 1) = Application.WorksheetFunction.Percentile(.Index(Current_MACD_Percentile_Arr, 1, 0), 0.985) 
        End With 

        Next x 

    With Worksheets("Program Requirements") 
    .Range(.Cells(5 + m - 1, 19), .Cells(Last_Row, 19)).Value = Current_MACD_Percentile 
    End With 
+0

FYI, код до этого выполняется примерно через 0,25 секунды, поэтому я точно знаю, что этот цикл является проблемой. – user2386878

ответ

0

Ваша проблема в петле внутри цикла. Вы упомянули в вопросе, что у вас 8000 строк, поэтому я предполагаю, что UBound (MoveArg5) составляет около 8000. Если это так, внутренний цикл работает 1 + 2 + 3 + 4 + .... + 8000 = (8000 * 8001)/2 = 32 миллиона раз! И вы перебираете свой массив с каждым циклом.

Плюс, внутренняя петля ничего не делает. Вы используете «For w = 1 to x», но затем внутри цикла вы не ссылаетесь на w, поэтому внутренний цикл просто не требует лишнего.

Кроме того, вы создали двумерные массивы, но только, кажется, используете только одно измерение (другое измерение всегда установлено в 1) - вы можете упростить, используя одномерные массивы.

Честно говоря, я не совсем уверен, что вы пытаетесь сделать здесь. Но если этот код «работает», но работает медленно, то полностью удалите цикл «For w = ...», оставив внутреннюю часть в цикле «For x =». Это должно ускорить процесс.

Или объясните, какой массив содержит ваши «сырые» данные.

EDIT:

Извините за задержку, занят на работе.

Так что, если ваши данные в MACD_SD_Pct (х, 1) вот вариант:

Dim TempArr() as Double, R as integer, AnswerArr() as Double 

Redim AnswerArr(UBound(MACD_SD_PCT,1)) 

For R=1 to UBound(MACD_SD_Pct,1) 
    Redim Preserve TempArr(R) 
    TempArr(R)=MACD_SD_Pct(R,1) 
    AnswerArr(R)=Application.WorksheetFunction.Percentile(TempArr,0.985) 
Next R 

Поскольку вы не писали какие-либо данных я не уверен, но это работало на 400 составили точки данных на листе.

+0

Спасибо за ответ. Этот цикл является лучшим способом, которым я знаю, как выполнить следующее: Строка 1 будет 98,5 процентиля строки 1, строка 2 будет 98,5 процентилем элементов массива 1 и 2, строка 3 будет 98,5 процентилем элементов массива 1 и 2 и 3 и т. д. До тех пор пока он не достигнет 8000 строк в MoveAvg5. Я знаю, почему он работает так медленно, я просто не знаю, как еще выполнить этот расчет. Измерение процентиля должно быть только от текущего положения элемента до нижней границы. Знаете ли вы, что лучше сделать это? Благодарю. – user2386878

+0

Я забыл добавить, исходные данные извлекаются из MACD_SD_Pct (x, 1). – user2386878