Re: RAD vs. performance
- From: "Curtis W" <cwarren89@xxxxxxxxx>
- Date: 3 Jul 2006 16:02:19 -0700
Dr Jon D Harrop wrote:
Curtis W wrote:I wasn't arguing that it's not possible in OCaml, but rather that it's
Dr Jon D Harrop wrote:
You're looking at the wrong example.
The other examples you gave were almost identical in functionality to
mine. I thought you didn't like my approach?
That's the point. You can write in your abstracted style easily in ML
but people do not do this because it weakens the typing, slows the code
and is rarely used in practice (in the context of numeric types, at
least).
underused and undersupported (by the compiler).
Only in the cases when the type is known at compile time. Actually, I'dIf you want it to handle something
else, you have to /rewrite/ it.
No, and I just gave you the code.
Of course, yours would actually be slower than mine, since yours has
abstractions that will be there, whereas my compiler can optimize them
away most of the time.
No, inlining the function arguments to the HOF recovers the original.
The only difference between the specialised and generic implementations
in OCaml is the passing of operators as function arguments.
forgotten about this--especially in something like math routines,
functions are generally going to be inlined. Inlining, unlike
specialisation, doesn't require full program optimisation, so your
point is moot 90% of the time.
You wouldn't use the full program compiler when you're developing.For factorial, yes. For functions in general, in the presence of
higher-order parameterised types, you're talking about n^m growth in
the complexity of your compiler, in the slowest part (the optimiser),
so your compile times must go through the roof in order to optimise
away the unwanted abstraction that you have imposed upon us.
Again, compile time doesn't matter so much when you only do it once per
release.
During development, you do it all the time.
This is even worse than I thought. A map function only requires anIt is empirical evidence that you are solving a problem that doesn't
need solving.
You mean, besides the fact that your standard library is so poorly
written because of this fact? Take a look at the array and list
functions--half of them are identical.
Again, can you provide any examples? I'm looking and I don't see what
you're claiming. For example, here is Array.map:
let map f a =
let l = length a in
if l = 0 then [||] else begin
let r = create l (f(unsafe_get a 0)) in
for i = 1 to l - 1 do
unsafe_set r i (f(unsafe_get a i))
done;
r
end
and here is List.map:
let rec map f = function
[] -> []
| a::l -> let r = f a in r :: map f l
where is all of this commonality and code duplication?!
iterable object--whether or not the object is an array or list is
irrelevant. Specifically, in my language map looks like this (types
present for clarity):
[code]
def map(xs:iterable, f):
ret = []
for x in xs:
ret.append_ip(f(x))
return ret
[/code]
(an iterable is any object with an 'iter' function, which returns an
iterator over the object; 'for' automatically handles all this)
It may not be immediately obvious, but the reason the two versions
above are different is solely because Array and lists don't expose the
same interface--namely, being able to deconstruct via the '::' operator
in pattern matching.
note: this is assuming the array version isn't in-place. It doesn't
look like it, although it's not particularly easy to understand. If it
is in place, then you're comparing apples to oranges.
The standard library (see above). Or, a real world example:Again, where is all of this code duplication?
In many, many pieces of OCaml code.
Give some examples, please.
http://www.gamedev.net/community/forums/topic.asp?topic_id=401651
True. This wouldn't be necessary in the two serious solutions IOnly slightly:
def factorial(x:int):
if x == 1: return x
else: return x*factorial(x-1)
3 characters, wow, that's really verbose!
Do you want to compete with static typing or don't you?
Write down the algorithm that the programmer must execute in order to
determine which code hot spots require type annotation. It's hard and
time consuming.
Profiling is?
Reading a profile is time consuming, even if we assume that your
profile will contain all of the type information that is required.
proposed.
As well as usage information, which can be in another module.Right, but you want the error catching that you can only get with whole
program recompilation when you're doing development, and that isn't
feasible.
What are you talking about? The type checker doesn't require whole
program compiling--the only reason the optimiser needs that is because
/it's changing a function/,
... according to its type.
Do you have any examples of how it "weakens type checking"?whereas a type checker simply verifies the
statements against publicly available type information from that
function.
This is a question of specificity. In ML, the factorial function has
the type int -> int and the type checker will unify this type with any
uses of this factorial function in order to type check the rest of the
program. A type-specific version in your language will have the same
type checking done. A type-generic (e.g. int | float) version in your
language can only have the same type checking guaranteed if whole
program analysis is used to examine every call site (monomorphisation).
Alternatively, you can type check the union type int|float but this is
weaker type checking (the type is not as specific) so it will not catch
as many bugs.
Which would happen rarely with a whole program optimiser. Specifically,In the vast majority of cases, we don't want that flexibility. It is
too loose.
How can you be "too loose"? I've already shown you that performance
would rarely be an issue and that type checking isn't harmed.
Performance is an issue. This abstraction in OCaml costs about an order
of magnitude in performance when applied to int vs float, which is
equivalent to the case of your compiler being unable to optimise away
your abstraction, i.e. the worst-case scenario for dynamic typing.
it would only happen when either 1) there's no way to optimise it,
period or 2) when the function is in a library and its usage isn't
known at compile time. The latter can be offset through the use of the
other method I posted.
So? Even then, it would still only be instantiating objects.The
parser doesn't even do anything other than instantiate types, so there
isn't even a problem there.
But the parser and evaluator might be mutually recursive (e.g. having
"load" function) unless the expr type is declared somewhere shared by
the two.
Only in the sense that over-abstraction is needless abstraction.Despite the fact that there is a lot of evidence to back up what I am
saying (e.g. performance of compilers and compiled dynamically typed
languages, utility of static checking) and little to back you up (e.g.
no code duplication, no aggressive factoring into HOFs).
What kind of response is that? I say premature optimisation is a bad
design decision and you throw me statistics on the performance of
compilers?
As I've said, we don't do this to optimise our code, we do it to
statically check our code to remove more bugs. Over-abstracting is
every bit as bad as premature optimisation. People just haven't
realised it yet...
Over-abstraction doesn't apply to libraries, since it's impossible to
know what people will or will not need.
Your assertion that type checking union types is somehow "more weak."It seems to me you're just throwing stuff out there,
now, since that doesn't even really make any sense.
What doesn't make sense?
.
- Follow-Ups:
- Re: RAD vs. performance
- From: Jon Harrop
- Re: RAD vs. performance
- References:
- Re: RAD vs. performance
- From: Jon Harrop
- Re: RAD vs. performance
- From: Curtis W
- Re: RAD vs. performance
- From: Jon Harrop
- Re: RAD vs. performance
- From: Curtis W
- Re: RAD vs. performance
- From: Jon Harrop
- Re: RAD vs. performance
- From: Curtis W
- Re: RAD vs. performance
- From: Dr Jon D Harrop
- Re: RAD vs. performance
- From: Curtis W
- Re: RAD vs. performance
- From: Dr Jon D Harrop
- Re: RAD vs. performance
- Prev by Date: Re: RAD vs. performance
- Next by Date: Re: RAD vs. performance
- Previous by thread: Re: RAD vs. performance
- Next by thread: Re: RAD vs. performance
- Index(es):
Relevant Pages
|