![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
From: Nicolas Alvarez
Subject: Re: A question about Java generics (not a flame)
Date: 9 May 2008 17:31:38
Message: <4824c2ba@news.povray.org>
|
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
> Orchid XP v8 wrote:
>>> Java supports generics.
>> ....OK, I just learned something.
>
> Are they actually supported as new types? Or is it just syntactic
> shorthand? I wouldn't think you could really have generics if you didn't
> change the .class file format, which I think Sun's trying to avoid?
>
http://java.sun.com/docs/books/tutorial/java/generics/erasure.html
http://java.sun.com/docs/books/tutorial/extra/generics/legacy.html
http://java.sun.com/docs/books/tutorial/extra/generics/convert.html
Basically, it looks like anything related to generics is removed from the
compiled code.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
From: Warp
Subject: Re: A question about Java generics (not a flame)
Date: 9 May 2008 20:49:51
Message: <4824f12e@news.povray.org>
|
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> For example, you have to parse and compile the
> templates each time from source
A compiler which supports export templates could conceivably have
precompiled templates for certain (although obviously not all) types,
such as for example for all basic types and STL classes. Thus it could
avoid having to compile them each time.
> and you get a new blob of code for each
> type you instantiate a template with.
If you are using the same code with two different types you are obviously
going to get two different pieces of code, no matter how you do it.
Templates just make it easier to avoid code repetition. (In other words,
if you want, for example, a vector of ints and a vector of doubles, you
don't need to write the vector code twice.)
Templated data containers in C++ usually produce more memory-efficient
code than equivalent data containers using the pointer-to-base-Object
mechanism, which usually wastes a lot of memory. Thus any argument that
templates cause memory bloat is usually false. (Yes, there may be a few
situations where templated code causes more memory usage, but normally
it's the opposite.)
> Now, "crippled" is what I'd call the baroque C++ syntax.
Syntax doesn't really matter all that much. It's how you use it.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
From: Orchid XP v8
Subject: Re: A question about Java generics (not a flame)
Date: 10 May 2008 08:28:30
Message: <482594ee@news.povray.org>
|
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>> So... it's Turing-complete?
>
> Yep.
Right. Well, the good thing about Turing-complete languages is that they
can do everything. The bad part is... they can do everything. SQL is so
damn efficient precisely *because* there are things it can't do.
Java's generics [if they anything like any other language] are nowhere
near Turing-complete, which makes them much easier to handle. [And
harder to misuse.]
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> For example, you have to parse and compile the
>> templates each time from source
>
> A compiler which supports export templates could conceivably have
> precompiled templates for certain (although obviously not all) types,
> such as for example for all basic types and STL classes. Thus it could
> avoid having to compile them each time.
Yes. If you restrict templates to doing what generics do, you don't have
to compile them each time. But that's a restriction on templates.
>> and you get a new blob of code for each
>> type you instantiate a template with.
>
> If you are using the same code with two different types you are obviously
> going to get two different pieces of code, no matter how you do it.
Not in every language, no. Depending on what you do with the types,
yes. That, for example, *is* one difference between generics and
templates. Obviously Java "generics" (such as they are) don't have this
restriction, because by the time you get to object code, all the actual
type information is gone.
In any case, what *I* meant was that you get a new blob of code compiled
every time you instantiate a template. Not for each different type, but
even for the same types in different compilation units. Yes? Or am I
confused about that? If I have std:vector<MyType> having functions
called in one module, then I compile another module with
std:vector<MyType>, does the linker see that it's the same code and
function on the same type and only include one copy of the object code
in the linked result?
> Templates just make it easier to avoid code repetition. (In other words,
> if you want, for example, a vector of ints and a vector of doubles, you
> don't need to write the vector code twice.)
Right. Generics do the same thing. They're just more restricted than
what templates give you.
> Templated data containers in C++ usually produce more memory-efficient
> code than equivalent data containers using the pointer-to-base-Object
> mechanism, which usually wastes a lot of memory.
Unless everything's already a pointer-to-base-Object, as you already
decry. ;-)
> Thus any argument that
> templates cause memory bloat is usually false. (Yes, there may be a few
> situations where templated code causes more memory usage, but normally
> it's the opposite.)
I think they likely cause code file bloat. If you use the same template
and instantiate it on 10 different types of pointers, aren't you going
to get ten different copies of object code?
>> Now, "crippled" is what I'd call the baroque C++ syntax.
> Syntax doesn't really matter all that much. It's how you use it.
True. It's a pretty minor thing, once you get used to it. I just dislike
people taking the syntax into languages that don't need it. Right up
there with people who think a leading zero means octal is a good idea on
values rather than constants.
--
Darren New / San Diego, CA, USA (PST)
"That's pretty. Where's that?"
"It's the Age of Channelwood."
"We should go there on vacation some time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
From: Warp
Subject: Re: A question about Java generics (not a flame)
Date: 10 May 2008 14:19:55
Message: <4825e74a@news.povray.org>
|
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Warp wrote:
> > Darren New <dne### [at] san rr com> wrote:
> >> For example, you have to parse and compile the
> >> templates each time from source
> >
> > A compiler which supports export templates could conceivably have
> > precompiled templates for certain (although obviously not all) types,
> > such as for example for all basic types and STL classes. Thus it could
> > avoid having to compile them each time.
> Yes. If you restrict templates to doing what generics do, you don't have
> to compile them each time. But that's a restriction on templates.
At least Java generics do not support basic types, so I don't really
understand what you are talking about.
I suppose that no compiler so far uses this optimization, but I can
perfectly imagine it being absolutely possible: When a template class or
function is instantiated for a certain type, the compiler could compile
it into some type of object file. Next time that template is used with
the same type (be it in the same compilation process, by another compilation
unit, or in a future one) it can simply use that object file instead of
recompiling the template code. The mechanism to do this could be similar
and related to export templates (or if technical reasons mandate it, it
could only work with export templates).
> In any case, what *I* meant was that you get a new blob of code compiled
> every time you instantiate a template. Not for each different type, but
> even for the same types in different compilation units. Yes? Or am I
> confused about that?
Currently yes, but as I said, it's perfectly conceivable that this
could be optimized by compilers.
> If I have std:vector<MyType> having functions
> called in one module, then I compile another module with
> std:vector<MyType>, does the linker see that it's the same code and
> function on the same type and only include one copy of the object code
> in the linked result?
The linker always merges all template instantiations of a given type
into one (this is required by the C++ standard, AFAIK). In other words,
the final executable will have only one instance of those functions.
That's not the problem.
(The only "problem" with template code is the increased compilation
time and object file sizes.)
> > Templates just make it easier to avoid code repetition. (In other words,
> > if you want, for example, a vector of ints and a vector of doubles, you
> > don't need to write the vector code twice.)
> Right. Generics do the same thing.
Except that they don't work with basic types, at least not in Java,
so they only solve part of the problem. :P
> > Thus any argument that
> > templates cause memory bloat is usually false. (Yes, there may be a few
> > situations where templated code causes more memory usage, but normally
> > it's the opposite.)
> I think they likely cause code file bloat.
The amount of code "bloat" caused by templates is usually much smaller
than the extra amount of RAM required if templates were avoided. Usually
template functions are relatively small, like some hundreds of bytes at
most, while the data containers they are instantiating handle even
megabytes of memory at a time. With C++ templates the optimization is
in the right place: In the memory usage of the data containers, not the
machine code in the functions of that data container.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On Sat, 10 May 2008 19:44:53 +0200, Darren New <dne### [at] san rr com> wrote:
> In any case, what *I* meant was that you get a new blob of code compiled
> every time you instantiate a template. Not for each different type, but
> even for the same types in different compilation units. Yes? Or am I
> confused about that? If I have std:vector<MyType> having functions
> called in one module, then I compile another module with
> std:vector<MyType>, does the linker see that it's the same code and
> function on the same type and only include one copy of the object code
> in the linked result?
Some compilers delay code generation of some templates until link time.
Even in the absence of delayed code generation, the linker merges
duplicates.
>> Thus any argument that
>> templates cause memory bloat is usually false. (Yes, there may be a few
>> situations where templated code causes more memory usage, but normally
>> it's the opposite.)
>
> I think they likely cause code file bloat. If you use the same template
> and instantiate it on 10 different types of pointers, aren't you going
> to get ten different copies of object code?
Some linkers can recognise that the generated code is identical, and merge
all the copies.
--
FE
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
From: Warp
Subject: Re: A question about Java generics (not a flame)
Date: 10 May 2008 15:14:06
Message: <4825f3fe@news.povray.org>
|
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Fredrik Eriksson <fe79}--at--{yahoo}--dot--{com> wrote:
> Some linkers can recognise that the generated code is identical, and merge
> all the copies.
Not "some". All of them. They have to.
That's because, AFAIK, as per the C++ standard, you have to be able to,
for example, create a function pointer to a given template function, and
if two pointers initialized in different compilation units point to the
same function, they have to compare equal. Another requisite is that if
there are static variables inside the function, they must all use the same
static variable.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On Sat, 10 May 2008 21:14:06 +0200, Warp <war### [at] tag povray org> wrote:
> Fredrik Eriksson <fe79}--at--{yahoo}--dot--{com> wrote:
>> Some linkers can recognise that the generated code is identical, and
>> merge all the copies.
>
> Not "some". All of them. They have to.
>
> That's because, AFAIK, as per the C++ standard, you have to be able to,
> for example, create a function pointer to a given template function, and
> if two pointers initialized in different compilation units point to the
> same function, they have to compare equal. Another requisite is that if
> there are static variables inside the function, they must all use the
> same static variable.
This is true for multiple definitions of the same object, but Darren was
talking about instantiations on multiple distinct types.
--
FE
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
From: Darren New
Subject: Re: A question about Java generics (not a flame)
Date: 10 May 2008 16:05:53
Message: <48260021@news.povray.org>
|
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> Warp wrote:
>>> Darren New <dne### [at] san rr com> wrote:
>>>> For example, you have to parse and compile the
>>>> templates each time from source
>>> A compiler which supports export templates could conceivably have
>>> precompiled templates for certain (although obviously not all) types,
>>> such as for example for all basic types and STL classes. Thus it could
>>> avoid having to compile them each time.
>
>> Yes. If you restrict templates to doing what generics do, you don't have
>> to compile them each time. But that's a restriction on templates.
>
> At least Java generics do not support basic types, so I don't really
> understand what you are talking about.
I'm saying you could pre-compile many templates if the templates only
are capable of doing what generics do.
> I suppose that no compiler so far uses this optimization, but I can
> perfectly imagine it being absolutely possible: When a template class or
> function is instantiated for a certain type, the compiler could compile
> it into some type of object file. Next time that template is used with
> the same type (be it in the same compilation process, by another compilation
> unit, or in a future one) it can simply use that object file instead of
> recompiling the template code.
Yes. Bingo. That's a generic. You can't do that with templates because
you (a) can't tell if the template will generate the same code with
different classes/parameters, and (b) you can't tell if the template
source code changed since you compiled those object files, because the
object files don't carry around information about the template source code.
That's basically how almost every other language implements generics.
> The mechanism to do this could be similar
> and related to export templates (or if technical reasons mandate it, it
> could only work with export templates).
I don't know what an "export template" is, so you may be right there.
>> In any case, what *I* meant was that you get a new blob of code compiled
>> every time you instantiate a template. Not for each different type, but
>> even for the same types in different compilation units. Yes? Or am I
>> confused about that?
>
> Currently yes, but as I said, it's perfectly conceivable that this
> could be optimized by compilers.
Sounds like it would be difficult, given that there's no relationship
the compiler can rely on between template sources and template object code.
> The linker always merges all template instantiations of a given type
> into one (this is required by the C++ standard, AFAIK). In other words,
> the final executable will have only one instance of those functions.
> That's not the problem.
OK. So the linker is doing duplicate-code removal. It also would seem to
assume that all your object code is compiled with the same template
source code? Or does it actually look at the object code to make sure
it's the same?
I.e., if I compile A.cpp that includes T.chh to instantiate
xyz:vector<long>, and then I edit T.chh and then compile B.cpp that
instantiates xyz:vector<long> but that now generated different code,
does the linker carry around both versions of the object code?
>> Right. Generics do the same thing.
>
> Except that they don't work with basic types, at least not in Java,
> so they only solve part of the problem. :P
Generics in Java aren't even really generics, since they get
type-erased. But yes, I'm not talking about "generics as implemented in
Java without actually changing any object code." I'm talking about when
people speak of generics in a language that actually supports generics,
like Eiffel or Ada, for example.
>>> Thus any argument that
>>> templates cause memory bloat is usually false. (Yes, there may be a few
>>> situations where templated code causes more memory usage, but normally
>>> it's the opposite.)
>
>> I think they likely cause code file bloat.
>
> The amount of code "bloat" caused by templates is usually
I wasn't aware the linker removed duplicate object code. That's the
bloat I was speaking of.
Some languages have restricted enough generics that you only need one
copy of the object file regardless of what you instantiate it on. Java
is like this, which is why it doesn't work with non-Object types -
basically, you instantiate it once for Object and the compiler just
checks you use it right at compile time.
--
Darren New / San Diego, CA, USA (PST)
"That's pretty. Where's that?"
"It's the Age of Channelwood."
"We should go there on vacation some time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Fredrik Eriksson wrote:
> This is true for multiple definitions of the same object, but Darren was
> talking about instantiations on multiple distinct types.
More precisely, I was speaking of the differences between generics and
templates, and why it's not unreasonable to say "we don't like
templates, we do like generics." Regardless of implementation
technology and optimizations...
--
Darren New / San Diego, CA, USA (PST)
"That's pretty. Where's that?"
"It's the Age of Channelwood."
"We should go there on vacation some time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |