views:

413

answers:

7

I have hit upon this problem about whether to use bignums in my language as a default datatype when there's numbers involved. I've evaluated this myself and reduced it to a convenience&comfort vs. performance -question. The answer to that question depends about how large the performance hit is in programs that aren't getting optimized.

How small is the overhead of using bignums in places where a fixnum or integer would had sufficed? How small can it be at best implementations? What kind of implementations reach the smallest overhead and what kind of additional tradeoffs do they result in?

What kind of hit can I expect to the results in the overall language performance if I'll put my language to default on bignums?

A: 

your reduction is correct, but the choice depends on the performance characteristics of your language, which we cannot possibly know!

once you have your language implemented, you can measure the performance difference, and perhaps offer the programmer a directive to choose the default

Steven A. Lowe
+3  A: 

To be honest, the best answer is "try it and see".

Clearly bignums can't be as efficient as native types, which typically fit in a single CPU register, but every application is different - if yours doesn't do a whole load of integer arithmetic then the overhead could be negligible.

Alnitak
A: 

You will never know the actual performance hit until you create your own benchmark as the results will vary per language, per language revision and per cpu and. There's no language independent way to measure this except for the obvious fact that a 32bit integer uses twice the memory of a 16bit integer.

TravisO
A: 

How small is the overhead of using bignums in places where a fixnum or integer would had sufficed? Show small can it be at best implementations?

The bad news is that even in the best possible software implementation, BigNum is going to be slower than the builtin arithmetics by orders of magnitude (i.e. everything from factor 10 up to factor 1000).

I don't have exact numbers but I don't think exact numbers will help very much in such a situation: If you need big numbers, use them. If not, don't. If your language uses them by default (which language does? some dynamic languages do …), think whether the disadvantage of switching to another language is compensated for by the gain in performance (which it should rarely be).

(Which could roughly be translated to: there's a huge difference but it shouldn't matter. If (and only if) it matters, use another language because even with the best possible implementation, this language evidently isn't well-suited for the task.)

Konrad Rudolph
That this (orders of magnitude cost) is false can easily be seen in practice from benchmark results. It works out that way because in the common case arithmetic is still on fixnums, plus a check for overflow.
Darius Bacon
@Darius: I'm talking about ranges that are no longer fixnums, here. In the other case, the rest of my text applies. Either: why use fixnumns? or: it doesn't matter, or: why, if it matters, do you use a language where you can't control it?
Konrad Rudolph
+2  A: 

You can perhaps look at how Lisp does it. It will almost always do the exactly right thing and implicitly convert the types as it becomes necessary. It has fixnums ("normal" integers), bignums, ratios (reduced proper fractions represented as a set of two integers) and floats (in different sizes). Only floats have a precision error, and they are contagious, i.e. once a calculation involves a float, the result is a float, too. "Practical Common Lisp" has a good description of this behaviour.

Svante
A: 

I totally doubt that it would be worth it, unless it is very domain-specific.

The first thing that comes to mind are all the little for loops throughout programs, are the little iterator variables all gonna be bignums? That's scary!

But if your language is rather functional... then maybe not.

chakrit
+2  A: 

Come to think of it... I don't think it will have much performance hits at all.

Because bignums by nature, will have a very large base, say a base of 65536 or larger for which is usually a maximum possible value for traditional fixnum and integers.

I don't know how large you would set the bignum's base to be but if you set it sufficiently large enough so that when it is used in place of fixnums and/or integers, it would never exceeds its first bignum-digit thus the operation will be nearly identical to normal fixnums/int.

This opens an opportunity for optimizations where for a bignum that never grows over its first bignum-digit, you could replace them with uber-fast one-bignum-digit operation.

And then switch over to n-digit algorithms when the second bignum-digit is needed.

This could be implemented with a bit flag and a validating operation on all arithmetic operations, roughly thinking, you could use the highest-order bit to signify bignum, if a data block has its highest-order bit set to 0, then process them as if they were normal fixnum/ints but if it is set to 1, then parse the block as a bignum structure and use bignum algorithms from there.

That should avoid performance hits from simple loop iterator variables which I think is the first possible source of performance hits.

It's just my rough thinking though, a suggestion since you should know better than me :-)

p.s. sorry, forgot what the technical terms of bignum-digit and bignum-base were

chakrit