Забавный вопрос.
1114 Итак, что же случилось? Хорошо, если вы выполните отладку с помощью gdb, вы увидите что-то вроде 3 переменных-членов (имена не точные):
_M_begin
: указатель на первый элемент динамического массива _M_end
: указатель на один за последним элементом динамического массива _M_capacity
: указатель на один за последним элементом, который может быть сохранен в динамическом массиве Реализация Таким образом, значение vector<T,Alloc>::size()
обычно сводится к:
return _M_end - _M_begin; // Note: _Mylast - _Myfirst in VC 2008
Теперь есть две вещи, которые следует учитывать при рассмотрении фактической возможной оптимизации:
Другими словами:
size
самостоятельно, есть большая вероятность, что он будет таким же быстрым, как компилятор мог его получить ... В любом случае, я серьезно сомневаюсь, что это стоит хлопот. В лучшем случае это микрооптимизация, которая вряд ли принесет большую пользу.
На этот вопрос есть лучшие ответы здесь: Выполнение функции с тайм-аутом
Futures на помощь!
user=> (let [f (future (reduce * (range 1 1001)))]
(.get f 1 java.util.concurrent.TimeUnit/MILLISECONDS))
java.util.concurrent.TimeoutException (NO_SOURCE_FILE:0)
И чтобы сделать макрос из этого:
(defmacro time-limited [ms & body]
`(let [f# (future ~@body)]
(.get f# ~ms java.util.concurrent.TimeUnit/MILLISECONDS)))
Итак, вы можете сделать это:
user=> (time-limited 1 (reduce * (range 1 1001)))
java.util.concurrent.TimeoutException (NO_SOURCE_FILE:0)
user=> (time-limited 1 (reduce * (range 1 101)))
93326215443944152681699238856266700490715968264381621468592963895217599993229915
608941463976156518286253697920827223758251185210916864000000000000000000000000
Я не уверен, что это возможно без выполнения выражения в отдельном потоке. Причина в том, что если поток занят обработкой выражения, вы не можете внедрить код для генерации исключения.
Версия с потоком монитора, который генерирует исключение, если выражение занимает слишком много времени, определенно возможна, однако выброшенное исключение будет из потока монитора, а не из потока, в котором выполняется выражение. Тогда не было бы способа остановить его, за исключением отправки этому потоку прерывания, которое он мог бы проигнорировать, если вы не закодировали его в выражении.
Если приемлемо иметь версию, которая запускает выражение в в отдельной ветке, дайте мне знать, и я могу опубликовать образец кода. Иначе, ваш лучший выбор звучит так, как будто это было бы написать основной цикл / рекурсию выражения таким образом, чтобы он проверял, сколько времени он занял на каждой итерации, и генерировал исключение, если оно превышало границу. Извините, если это не совсем то, что вам нужно ...