2016-08-09 2 views
-1

Пожалуйста, рассмотрите этот общий кусок кода:Эффективный способ проверки имущества из большого набора данных внутри цикла

for j = 0 to (Array.length myArray) - 1 do 
    if property.(id) then 
     (* do a bunch of stuff*) 
done 

Здесь property очень большой массив логических значений. В этом эксперименте мы имеем 2 случая:

  • в 1-й, property.(id) всегда правда.

  • Во втором, property.(id) может быть либо истинным или ложным.

Мы хотим, чтобы 2-й случай выиграл, так как он пропускает выполнение кода. Но этого не происходит из-за кондиционирования ветвей. Мы также пробовали разбивку property вместо инструкции if, но 1-й случай все еще выигрывает. (Это все предложения членов сообщества OCaml).

Наша проблема : мы можем обнаружить свойство, которое позволяет нам пропустить часть кода. Но использование большого логического массива для сохранения того элемента, который имеет это свойство, делает проверку самого свойства медленнее, чем сохраненное выполнение кода.

Таким образом, вопрос сейчас более общий: какой лучший способ реализации этой проблемы?

Мы действительно ценим любое предложение сообщества.

+0

Вы пишете: «Мы хотим, чтобы второй случай выиграл, так как он пропускает выполнение кода, но этого не происходит из-за кондиционирования ветвей. Мы также попробовали свойство разбиения вместо утверждения if, но 1-й случай все еще выигрывает «. Это может быть справедливо только в том случае, если ваша «куча вещей» в теле цикла является довольно быстрой. Это действительно так? Вы также пишете: «(Все это предложения членов сообщества OCaml)». Это помогло бы дать указатель на эти «предложения». – FPstudent

+0

@FPstudent, спасибо за ответ. Мы ожидаем выиграть 2-й случай, так как * куча вещей * включает арифметические операции.То есть, мы держим пари, что проверка булевского выражения будет быстрее, чем выполнение математической операции. Если это не всегда так, мы рады сообщить об отрицательных результатах. Мы просто хотим убедиться, что отрицательные результаты не из-за плохой реализации. Предложения сообщества OCaml были предоставлены во время разговора в их [IRC-канале] (https://kiwiirc.com/client/irc.freenode.net/?#ocaml). К сожалению, у меня нет журнала. – jhonatanoliveira

ответ

0

На мой взгляд, есть два возможных решения вашей проблемы:

  • Если вы все еще хотите использовать для цикла, то я предлагаю использовать исключение для выхода из для цикла

    exception YourExn of something 
    
    try 
        for j = 0 to (Array.length property) - 1 do 
        if property.(id) then 
         (* do a bunch of stuff*) 
        else raise (YourExn result) 
        done 
    with YourExn res -> (* do something *) 
    

    исключение YourExn чего-то

  • Другим решением является просто написать рекурсивную функцию вместо того, чтобы использовать для цикла. Я предлагаю использовать это решение, так как использование рекурсивной функции является своего рода стандартом в функциональном программировании.

    let rec traverse property id = 
        if id > (Array.length property) then 
        (* exit *) 
        else if property.(id) then 
        (* do a bunch of stuff*) 
        traverse property (id + 1) 
        else 
        (* exit *) in 
    
    traverse property 0 
    
+0

Спасибо, @Trung Ta. Проблема с вашим решением - это 'if': в обоих случаях' if property. (Id) then' попадет в эту проблему, которую я описал. – jhonatanoliveira

+0

Вы можете создать исключение внутри ветки 'if ... then'. Это самый быстрый способ выйти из вычисления –

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