Самый быстрый способ вычислить начала в C#?

Я использую это, и он работает. http://codesheet.org/codesheet/NF246Tzs

function getUrlVars() {
    var vars = {};
    var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
    vars[key] = value;
    });
return vars;
}


var first = getUrlVars()["id"];

10
задан Mark Cidade 29 December 2008 в 22:26
поделиться

7 ответов

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

Кроме того, в устранении позже составляет композит, после того как Вы поражаете новый главный p впервые - первый составной объект, несколько остающиеся p будут p*p, начиная со всего, прежде чем это было уже устранено. На самом деле только необходимо умножить p на все остающиеся потенциальные начала, которые оставляют после него в списке, останавливаясь, как только продукт вне диапазона (больше, чем До).

Существуют также некоторые хорошие вероятностные алгоритмы там, такие как тест Miller-Rabin. Страница Википедии является хорошим введением.

5
ответ дан 4 December 2019 в 02:27
поделиться

Распараллеливание в стороне, Вы не хотите вычислять sqrt (До) на каждое повторение. Также можно принять кратные числа 2, 3 и 5 и только вычислить для N%6 в {1,5} или N%30 в {1,7,11,13,17,19,23,29}.

Необходимо смочь параллелизировать алгоритм факторинга довольно легко, так как Энный этап только зависит от sqrt (n) th результат, так через некоторое время не будет никаких конфликтов. Но это не хороший алгоритм, так как требуется много подразделения.

Необходимо также смочь параллелизировать алгоритмы решета, если Вы сделали, чтобы устройство записи работало пакеты, которые, как гарантируют, завершатся перед чтением. Главным образом устройства записи не должны конфликтовать с читателем - по крайней мере, после того как Вы сделали несколько записей, они должны работать, по крайней мере, N выше читателя, таким образом, Вам только нужно синхронизируемое чтение справедливо иногда (когда N превышает последнее синхронизируемое значение чтения). Вы не должны должны быть синхронизировать массив bool через любое количество потоков устройства записи, так как конфликты записи не возникают (в худшем случае, больше чем один поток запишет истинное для того же места).

Основной вопрос состоял бы в том, чтобы гарантировать, что любой рабочий, ожидающий на записать, завершился. В C++ Вы использовали бы сравнивать-и-устанавливать для переключения на рабочего, для которого ожидают в любой точке. Я не зубрила C#, так не знайте, как сделать это, что язык, но функция Win32 InterlockedCompareExchange должен быть доступным.

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

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

2
ответ дан 4 December 2019 в 02:27
поделиться

Не представляя мы не можем сказать, какому биту программы нужна оптимизация.

Если бы Вы были в большой системе, то можно было бы использовать профилировщика, чтобы найти, что генератор простого числа является частью, которой нужна оптимизация.

Профилирование цикла приблизительно с дюжиной инструкций в нем обычно не имеет смысл - издержки профилировщика являются значительными по сравнению с телом цикла, и о единственных способах улучшить цикл, настолько маленький, должен изменить алгоритм, чтобы сделать меньше повторений. Так IME, после того как Вы устранили любые дорогие функции и имеете известную цель нескольких строк простого кода, Вы - более обеспеченное изменение алгоритма и синхронизация сквозного выполнения, чем попытка улучшить код профилированием уровня инструкции.

1
ответ дан 4 December 2019 в 02:27
поделиться

Также необходимо рассмотреть возможное изменение алгоритмов.

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

Возможно, предварительно выделяя пространство для Вашего списка, сделает более дешевым создать/заполнить.

0
ответ дан 4 December 2019 в 02:27
поделиться

@DrPizza, Представляющий только действительно, помогает улучшить реализацию, он не показывает возможности для параллельного выполнения или предлагает лучшие алгоритмы (если у Вас нет опыта к иначе, в этом случае я действительно хотел бы видеть Вашего профилировщика).

Я имею только одноядерные машины дома, но выполнил Java, эквивалентный из Вашего решета BitArray и единственной потоковой версии инверсии решета - содержание начал маркировки в массиве и использования колеса для сокращения пространства поиска фактором пять, затем отметив немного массива в инкрементах колеса с помощью каждой главной маркировки. Это также уменьшает устройство хранения данных до O (sqrt (N)) вместо O (N), который помогает и с точки зрения самого большого N, подкачки страниц и с точки зрения пропускной способности.

Для средних значений N (1e8 к 1e12), начала до sqrt (N) могут быть найдены вполне быстро, и после этого необходимо смочь параллелизировать последующий поиск на ЦП довольно легко. На моей одноядерной машине подход колеса находит начала до 1e9 в 28, тогда как Ваше решето (после перемещения sqrt из цикла) берет 86 - улучшение происходит из-за колеса; инверсия означает, что Вы можете обработать N больше, чем 2^32, но делаете ее медленнее. Код может быть найден здесь. Вы могли параллелизировать вывод результатов наивного решета после движения мимо sqrt (N) также поскольку битовый массив не изменяется после той точки; но после того как Вы имеете дело с N, достаточно большим, чтобы имело значение, что размер массива является слишком большим для ints.

0
ответ дан 4 December 2019 в 02:27
поделиться

Вы пытаетесь найти новые начала? Это может звучать глупым, но Вы смогли загружать своего рода структура данных с известными началами. Я уверен, что у кого-то там есть список. Это могла бы быть намного более легкая проблема для нахождения существующих чисел, которые вычисляют новые.

Вы могли бы также посмотреть на Параллель Microsofts Библиотека FX для того, чтобы сделать Ваш существующий код многопоточным для использования в своих интересах многоядерных систем. С минимальными изменениями кода можно сделать Вас для циклов многопоточными.

0
ответ дан 4 December 2019 в 02:27
поделиться

Существует очень хорошая статья о Решете Эратосфена: Подлинное Решето Эратосфена

Это находится в функциональной установке, но большинство opimization действительно также относится к процедурной реализации в C#.

Две самой важной оптимизации должна начать пересечение в P^2 вместо 2*P и использовать колесо для следующих простых чисел.

Для параллелизма можно обработать все числа до P^2 параллельно к P, не делая никакой ненужной работы.

0
ответ дан 4 December 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: