int size = myHashSet.size();
int item = new Random().nextInt(size); // In real life, the Random object should be rather more shared than this
int i = 0;
for(Object obj : myhashSet)
{
if (i == item)
return obj;
i++;
}
Как говорит jfk, наиболее распространенный способ сделать это - привязать скорость процессора к вертикальному обновлению (эмулированного) видеовыхода .
Выберите число циклов, выполняемых на каждый видеокадр. Это часто зависит от машины, но вы можете рассчитать это примерно так:
cycles = clock speed in Hz / required frames-per-second
Затем вы также можете перейти в спящий режим, пока не произойдет обновление видео, после чего вы начнете следующие n циклов эмуляции процессора.
Если вы эмулируете что-то конкретное, вам просто нужно посмотреть частоту кадров в секунду и скорость процессора, чтобы получить это примерно правильно.
РЕДАКТИРОВАТЬ: Если у вас нет требований к внешней синхронизации, то для эмулятора нормально просто беги так быстро, как только сможешь. Иногда это желаемый эффект, а иногда нет :)
Скорее всего, нечто подобное происходит и в вашем случае.
Чтобы сказать что-то более определенное, мне нужно увидеть определение функции.
Обновление:
SQL Server
может вставлять предикаты в функцию.
Например, я только что создал этот TVF
:
CREATE FUNCTION fn_test()
RETURNS TABLE
AS
RETURN (
SELECT *
FROM master
);
Эти запросы:
SELECT *
FROM fn_test()
WHERE name = @name
SELECT TOP 1000 *
FROM fn_test()
WHERE name = @name
приводят к другому выполнению планы (первый использует кластерное сканирование, второй использует поиск по индексу с TOP
)
Ваш TOP не имеет ORDER BY, поэтому он просто такой же, как SET ROWCOUNT 6000 first. ORDER BY потребует, чтобы в первую очередь оценивались все строки, а это займет намного больше времени.
Если dbo.some_table_function
представляет собой udf со встроенной таблицей, то это просто макрос, который расширяется, поэтому он возвращает первые 6000 строк, как указано, в произвольном порядке.
Если udf многозначный, то это черный ящик, и он всегда будет извлекать полный набор данных перед фильтрацией. Я не думаю, что это происходит.
Не имеет прямого отношения, но еще один вопрос SO по TVF
Не обязательно, чтобы вся таблица обрабатывалась, если у col1 есть индекс.
Оптимизация SQL выберет, использовать ли индекс или нет. Возможно, ваш «TOP» заставляет его использовать индекс.
Если вы используете анализатор запросов MSSQL (имя ускользает от меня), нажмите Ctrl-K. Это покажет план выполнения запроса вместо его выполнения. Думаю, наведение курсора на значки покажет использование ввода-вывода / процессора.
Готов поспорить, один использует поиск по индексу, а другой - нет.
Если у вас общий клиент: УСТАНОВИТЬ SHOWPLAN_ALL ON; ИДТИ Выбрать ...; go
подробности см. http://msdn.microsoft.com/en-us/library/ms187735.aspx .
Я думаю, что предложение Квасснуа кажется очень правдоподобным. Добавляя TOP 6000, вы неявно даете оптимизатору подсказку, что будет возвращено довольно небольшое подмножество из 200 000 строк. Затем оптимизатор использует поиск по индексу вместо сканирования кластерного индекса или просмотра таблицы.
Другим возможным объяснением может быть кеширование, как предлагает Джим Дэвис. Это довольно легко исключить, повторно запустив запросы. Попробуйте сначала запустить один с TOP 6000.
Вы можете столкнуться с такой простой задачей, как кеширование - возможно (по какой-либо причине) запрос "TOP" кэшируется? Используете индекс, которого нет у другого?
В любом случае лучший способ удовлетворить ваше любопытство - изучить полный план выполнения для обоих запросов. Вы можете сделать это прямо в консоли управления SQL, и она ТОЧНО сообщит вам, какие операции выполняются и сколько времени займет каждая из них.
Все реализации SQL по-своему необычны - SQL Server не исключение. Этакое «чтоаааааа ?!» моменты довольно распространены. ; ^)