Накладные расходы на использование bignums - PullRequest
2 голосов
/ 07 ноября 2008

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

Насколько малы издержки на использование бигнумов в местах, где было бы достаточно фикснума или целого числа? Насколько маленьким он может быть в лучшем случае? Какие реализации достигают наименьших издержек и к каким дополнительным компромиссам они приводят?

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

Ответы [ 7 ]

4 голосов
/ 07 ноября 2008

Вы можете посмотреть, как это делает Лисп. Он почти всегда будет выполнять операции точно правильно и неявно преобразовывать типы по мере необходимости. Он имеет фиксированные значения («нормальные» целые числа), bignums, отношения (сокращенные собственные дроби, представленные в виде набора из двух целых чисел) и числа с плавающей запятой (разных размеров). Только ошибки с плавающей точкой имеют погрешность точности, и они заразны, то есть, если вычисление включает в себя число с плавающей точкой, результатом также является число с плавающей точкой. «Практический Common Lisp» хорошо описывает это поведение.

3 голосов
/ 07 ноября 2008

Если честно, лучший ответ - "попробуй и посмотри".

Очевидно, что bignums не могут быть такими же эффективными, как нативные типы, которые обычно помещаются в один регистр ЦП, но каждое приложение отличается - если у вас нет полной загрузки целочисленной арифметики, тогда издержки могут быть незначительными.

2 голосов
/ 07 ноября 2008

Если подумать ... Я не думаю, что у него будет много хитов производительности.

Поскольку bignums по своей природе будут иметь очень большое основание, скажем, основание 65536 или больше, для которого обычно максимально возможное значение для традиционного фикснума и целых чисел.

Я не знаю, насколько большим вы бы задали основание bignum, но если вы установите его достаточно большим, чтобы при использовании вместо фиксированных чисел и / или целых чисел оно никогда не превышало его первую цифру bignum таким образом, операция будет практически идентична обычным фиксам / int.

Это открывает возможность для оптимизаций, когда для bignum, который никогда не растет по сравнению с его первой bignum-цифрой, вы могли бы заменить их сверхбыстрой операцией с одной цифрой.

А затем переключитесь на n-разрядные алгоритмы, когда потребуется вторая двузначная цифра.

Это может быть реализовано с битовым флагом и проверочной операцией для всех арифметических операций, грубо говоря, вы можете использовать бит высшего порядка для обозначения bignum, если блок данных имеет бит самого высокого порядка, установленный в 0, тогда обрабатывать их, как если бы они были обычными фиксированными значениями / целочисленными значениями, но если для него задано значение 1, проанализировать блок как структуру bignum и использовать оттуда алгоритмы bignum.

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

Это всего лишь мое грубое мышление, предложение, поскольку вы должны знать лучше меня: -)

p.s. извините, забыл, что технические термины bignum-digit и bignum-base были

0 голосов
/ 07 ноября 2008

Я полностью сомневаюсь, что оно того стоит, если только оно не очень специфично для домена.

Первое, что приходит на ум, это все маленькие циклы for в программах , все ли переменные маленького итератора будут бигнумами? Это страшно!

Но если ваш язык довольно функциональный ... то, возможно, нет.

0 голосов
/ 07 ноября 2008

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

Плохая новость заключается в том, что даже в наилучшей из возможных программных реализаций BigNum будет на несколько порядков медленнее встроенной арифметики (т. Е. От 10 до 1000).

У меня нет точных чисел, но я не думаю, что точные числа очень помогут в такой ситуации: если вам нужны большие числа, используйте их. Если нет, не надо. Если ваш язык использует их по умолчанию (какой язык делает? Некоторые динамические языки делают…), подумайте, компенсируется ли недостаток перехода на другой язык увеличением производительности (которым оно должно быть редко).

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

0 голосов
/ 07 ноября 2008

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

0 голосов
/ 07 ноября 2008

ваше сокращение корректно, но выбор зависит от характеристик вашего языка, которые мы не можем знать !

Как только вы внедрили свой язык, вы можете измерить разницу в производительности и, возможно, предложить программисту директиву по умолчанию

...