2015-11-24 3 views
3

Кроме того, как только появится расписание на постоянной пересылке case, что могло бы стать другим моментом для меня? case вместо condcondp?Case case in Clojure

+0

+1 +1 вопрос. В моем сценарии, где задействовано большое количество сравнения строк, я нашел, что использование 'condp' значительно быстрее, чем использование' case', что не имеет смысла. Однако я подозреваю, что это связано с флагами оптимизации. – Davyzhu

+0

@ Дайжу Интересно. Сколько случаев у вас было в ваших условиях (состояниях)? –

+0

@Elogent Я тестировал с профилированием уровня инструмента, а количество условий варьировалось от 3 до 10. Все они, даже в случае с 10 ветвями, 'condp' работают лучше, чем' case'. – Davyzhu

ответ

6
  1. Предполагая, что вы действительно имеете дело с константами времени компиляции, case семантически передает характер вашего состояния лучше, чем cond или condp.
  2. case более краткий, чем cond или condp.

Пример:

(cond 
    (= foo 1) :one 
    (= foo 2) :two 
    (= foo 3) :three) 

(condp = foo 
    1 :one 
    2 :two 
    3 :three) 

(case foo 
    1 :one 
    2 :two 
    3 :three) 

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

3

Даже там, где это медленнее, case часто более выразительным, чем if:

(defn fact [n] 
    (case n 
    0 1 
    (* n (fact (dec n))))) 

... читает лучше, чем

(defn fact [n] 
    (if (zero? n) 1 
    (* n (fact (dec n))))) 

Это дело вкуса, но case фраза одна форма короче.

+0

очень приятный 'факт'! кстати, что вы имеете в виду более выразительно? это краткость форм и элегантности для глаз, основные отличия от тех форм, которые менее красивы? и из вашего факта я могу сказать, что только форма оценивается в 'case' является последней формой * по умолчанию *? – amirteymuri

+0

@AmirTeymuri Да и нет. На первый взгляд, элегантность способствует пониманию по определению, я думаю. Во второй точке алгоритм является правильно рекурсивным, поэтому медленным и ограниченным до ~ 10K. И он взрывается переполнением стека задолго до этого: в 21 (замените '*' на '* '', чтобы вылечить это). Форма по умолчанию оценивается при каждом вызове, но самая глубокая. Отрицательные или нулевые аргументы также переполняют стек. Так что это довольно дрянной алгоритм, просто для иллюстрации. – Thumbnail

+0

@ Thumbnail Действительно; Я бы, вероятно, использовал его как '(apply * '(диапазон 1 (inc n))). –