[Prev][Next][Index][Thread]
Re: Representing percentage
On Sun, 28 Jan 2001 15:56:28 +0200, Nimi <nimi@better.tv> wrote:
>Hi,
>
> I'm trying to find a simple way to represent percentage. I thought of doing
> it like this:
>
> define constant <percentage> = limited(<integer>, min: 0, max: 100);
>
> But this is no good if I want to make a generic function that
> specializes on both <integer> (for absolute values, say, the number
> of elements in in a collection passed as another argument) and
> <percentage> (the relative size of the other argument) -
>
> This problem is solved if I do it this way:
>
> define class <percentage> (<number>)
> slot p :: limited(<integer>, min: 0, max: 100);
> end class;
>
> but it doesn't seem very efficient. Is there a better way to do it?
If you have both percentages and absolute sizes floating around your
program, you have to discriminate between the two. The type header in
<percentage> does that for you. You can also add an argument to the
function like
define function foo (c :: <collection>,
x :: <integer>,
percentage? :: <boolean>)
if (percentage?)
// treat x as a percentage
else
// treat x as a number of elts
end if
end function foo;
to discriminate manually. But as you no doubt can see this is really
questionable style.
I have to ask, is your <percentage> class really making your code
inefficient? Unless you have a few million instances of <percentage>
in your program floating around I'd be greatly surprised if it added a
measurable overhead to your program. Only if it were in an inner
loop, and if that loop had no other allocation, would the
boxing/unboxing overhead of <percentage> be a performance hit. Write
the class, and if (and only if) it causes a bottleneck, optimize it.
[If it is, then here's a Gwydion-specific optimization trick.
define functional class <percentage> (<number>)
slot p :: limited(<integer>, min: 0, max: 100),
required-init-keyword: p;
end class <percentage>;
define method functional-== (a :: <percentage>, b :: <percentage>)
=> (ans :: <boolean>)
a.p == b.p
end method functional-==;
define method functional-== (a :: <percentage>, b :: <object>)
=> (ans :: <boolean>)
#f
end method functional-==;
define method functional-== (a :: <object>, b :: <percentage>)
=> (ans :: <boolean>)
#f
end method functional-==;
This creates a class that behaves like <integer> and <character> do --
for these instances identity and equality are the same. The neat bit
is that when the functional object can fit into a word (plus
appropriate type declarations in effect), no memory allocation
happens. Thus it's just as efficient as <integer>.]
Neel
Follow-Ups:
References: