Board index » cppbuilder » Re: Trie?

Re: Trie?


2006-04-05 10:21:01 PM
cppbuilder45
"Ed Mulroy" < XXXX@XXXXX.COM >wrote in message
Quote
I agree that using a class instead of a struct might be a better way to do
it. What I do not agree with is that the use of a struct is a fault in
the
program or is something that is wrong with the program.
We would see it more as a fault in documentation of the design.
Our standard practice requires using classes to describe objects
and structures to be used when it's just a way of associating a
bunch of data. We don't allow public member data in classes.
AFAICS it's just a design thing.
I don't think Chris is saying it's an error in the program. Some
people convert all structures to classes because it's c++. Again,
it's not really an error, just a design issue.
 
 

Re:Re: Trie?

FWIW:
In my code structures have only data except occasionally constructors with
empty bodies but an initialization list (allows easy syntax when defining
arrays of structures) and possibly static functions (for things like radians
vs degrees).
The exception is when wrapping something else that is already provided as a
structure such as Windows' RECT structure.
. Ed
Quote
Duane Hebert wrote in message
news:4433d248$ XXXX@XXXXX.COM ...

We would see it more as a fault in documentation of the design.
Our standard practice requires using classes to describe objects
and structures to be used when it's just a way of associating a
bunch of data. We don't allow public member data in classes.

AFAICS it's just a design thing.

I don't think Chris is saying it's an error in the program. Some
people convert all structures to classes because it's c++. Again,
it's not really an error, just a design issue.
 

Re:Re: Trie?

Quote
In my code structures have only data except occasionally constructors with
empty bodies but an initialization list (allows easy syntax when defining
arrays of structures) and possibly static functions (for things like
radians
vs degrees).
It's about the same with us. I usually add empty ctors with init lists,
especially
when I want to init them with some default values like:
somestruct someinstance = {0};
(I prefer that over memset and such.)
Especially useful when the structs represent tables in a database.
Mostly structures are just containers of associated public data.
It's really just a design issue though. But then again, classes with
public data members can be thought of as a design issue as well.
 

{smallsort}

Re:Re: Trie?

"Ed Mulroy" < XXXX@XXXXX.COM >writes:
Quote
FWIW:

In my code structures have only data except occasionally constructors with
empty bodies but an initialization list (allows easy syntax when defining
arrays of structures) and possibly static functions (for things like radians
vs degrees).
I do that too, but it seems over time I need to add "just a little"
behavior, then "a little more" and before I know it, I've got a really
badly designed class.
In every case, I rewrite it to be a real class, and usually regret
that I didn't do it that way from the beginning. It's less work,
IMHO, if you have to change the interface at all.
--
Chris (TeamB);
 

Re:Re: Trie?

Chris Uzdavinis (TeamB) < XXXX@XXXXX.COM >writes:
Quote
In every case, I rewrite it to be a real class, and usually regret
that I didn't do it that way from the beginning. It's less work,
IMHO, if you have to change the interface at all.
I meant to say, "In every case where this happens...", not that every
case where a struct with a constructor appears it gets rewritten.
--
Chris (TeamB);
 

Re:Re: Trie?

"Jonathan Benedicto" < XXXX@XXXXX.COM >wrote in message
Quote
Duane Hebert wrote:
>Probably doesn't matter but why do you use
>__fastcall here?

So that the parameters are passed in the register. I thought that this
would
help its performance.
There was an article in BCB Journal (I think that's where I read it) that
did some performance testing on this. It turns out that __fastcall can
actually degrade performace, so the recommendation is to avoid using it
except when it is required.
- Dennis
 

Re:Re: Trie?

"Dennis Jones" < XXXX@XXXXX.COM >writes:
Quote
There was an article in BCB Journal (I think that's where I read it)
that did some performance testing on this. It turns out that
__fastcall can actually degrade performace, so the recommendation is
to avoid using it except when it is required.
That is rather surprising to me. How could registers be slower? But
history has shown that programmers are usually the worst people to
guess where true bottlenecks are in programs. Case in point.
As an aside, this is why optimizations should be suppressed until a
profiler is used and a true bottleneck is found, rather than
optimizing what we assume to be a slow part of our application.
--
Chris (TeamB);
 

Re:Re: Trie?

Quote
That is rather surprising to me. How could registers be slower? But
history has shown that programmers are usually the worst people to
guess where true bottlenecks are in programs. Case in point.
I tend to avoid __fastcall due to portability issues. I did read (probably)
the same article though. I got the impression that using registers
was only an attempt. Some overhead was introduced when it
failed. Not sure about that as I can't find the article any longer.
I do know that I've benchmarked this and found no measurable
benefit. I can't say that it cost anything except portability though.
 

Re:Re: Trie?

Duane Hebert wrote:
Quote
I tend to avoid __fastcall due to portability issues. I did read (probably)
the same article though. I got the impression that using registers
was only an attempt. Some overhead was introduced when it
failed. Not sure about that as I can't find the article any longer.

I do know that I've benchmarked this and found no measurable
benefit. I can't say that it cost anything except portability though.
I believe it depends on the function being called.
If it can use the register values immediately, then return, or
otherwise ignore them (no need to store them locally) then it can be a
bit faster. (Though a good compiler can optimize out the speed
improvements.)
 

Re:Re: Trie?

"Duane Hebert" < XXXX@XXXXX.COM >wrote in message
Quote
>That is rather surprising to me. How could registers be slower? But
>history has shown that programmers are usually the worst people to
>guess where true bottlenecks are in programs. Case in point.

I tend to avoid __fastcall due to portability issues. I did read
(probably)
the same article though. I got the impression that using registers
was only an attempt. Some overhead was introduced when it
failed. Not sure about that as I can't find the article any longer.

I do know that I've benchmarked this and found no measurable
benefit. I can't say that it cost anything except portability though.
The BCBJ article (public -- so anyone can read it) is here:
tinyurl.com/jshvt
- Dennis
 

Re:Re: Trie?

"Dennis Jones" < XXXX@XXXXX.COM >writes:
Quote
The BCBJ article (public -- so anyone can read it) is here:
tinyurl.com/jshvt
Thanks. I havn't seen Kent since he quit TeamB, but I have always
respected his work. However, as I understand the register convention
definition, it only will consider using registers for 2 or fewer
parameters, yet the benchmark is always passing 3 arguments to each
function. Thus, it will always hit the "worst case" of __fastcall,
and never actually measure the effects of placing the arguments in
registers. I wish the test also tested functions taking 1 or 2
parameters, and contrasted the results.
Is it the case that the first two arguments are placed in registers
and the remainder are on the stack (if there are more than 2), or is
it that the case that if there are more than 2 arguments, then ALL of
them are on the stack and none go into registers? Also, I'm not sure
if Borland's __fastcall has the same meaning as Microsoft's
__fastcall.
--
Chris (TeamB);
 

Re:Re: Trie?

Chris Uzdavinis wrote:
Quote
respected his work. However, as I understand the register convention
definition, it only will consider using registers for 2 or fewer
parameters,

Is it the case that the first two arguments are placed in registers
and the remainder are on the stack (if there are more than 2), or is
it that the case that if there are more than 2 arguments, then ALL of
them are on the stack and none go into registers? Also, I'm not sure
if Borland's __fastcall has the same meaning as Microsoft's
__fastcall.
_fastcall places the first 3 values in registers, the rest on the
stack. If there is a hidden 'this', then that would be the first
parameter, and only 2 more specified parameters would be by register.
 

Re:Re: Trie?

Chris Uzdavinis wrote:
Quote
"Dennis Jones" < XXXX@XXXXX.COM >writes:

>The BCBJ article (public -- so anyone can read it) is here:
>tinyurl.com/jshvt

Thanks. I havn't seen Kent since he quit TeamB, but I have always
respected his work.
Not to cast aspersions, but I get very different results:
- - - - - fastcall.c - - - -
#include <windows.h>
#include <stdio.h>
#include <conio.h>
int _pascal GetValueA(int x,int y,int z)
{
return x + y + z;
}
int _cdecl GetValueB(int x,int y,int z)
{
return x + y + z;
}
int _stdcall GetValueC(int x,int y,int z)
{
return x + y + z;
}
int _fastcall GetValueD(int x,int y,int z)
{
return x + y + z;
}
int _fastcall GetValueE(int x,int y )
{
return x + y + 3;
}
int main(void)
{
#define LOOPSIZE 100000000
int i, result;
DWORD A,B,C,D,E,Start;
Start = GetTickCount();
while( Start == GetTickCount() );
for( i=0; i<LOOPSIZE; ++i )
result = GetValueA( 1,2,3 );
A = GetTickCount();
while( A == GetTickCount() );
for( i=0; i<LOOPSIZE; ++i )
result = GetValueB( 1,2,3 );
B = GetTickCount();
while( B == GetTickCount() );
for( i=0; i<LOOPSIZE; ++i )
result = GetValueC( 1,2,3 );
C = GetTickCount();
while( C == GetTickCount() );
for( i=0; i<LOOPSIZE; ++i )
result = GetValueD( 1,2,3 );
D = GetTickCount();
while( D == GetTickCount() );
for( i=0; i<LOOPSIZE; ++i )
result = GetValueE( 1,2 );
E = GetTickCount();
E -= D;
D -= C;
C -= B;
B -= A;
A -= Start;
printf( "\r\nPascal\t\t%i"
"\r\nC\t\t%i"
"\r\nStdcall\t\t%i"
"\r\nFastCall\t%i"
"\r\nFastCall 2\t%i",
A,B,C,D,E );
getch();
return 0;
}
- - - - -
Run on my 2 GHz Celeron
C:\test>fastcall
Pascal 741
C 741
Stdcall 741
FastCall 531
FastCall 2 521
C:\test>
 

Re:Re: Trie?

At 18:29:52, 10.04.2006, Chris Uzdavinis (TeamB) wrote:
Quote
Also, I'm not sure
if Borland's __fastcall has the same meaning as Microsoft's
__fastcall.
No, they are different. MS only uses two registers, AFAIK, while
BCB/Delphi use three. In BCB, you can emulate that with __msfastcall
instead of __fastcall.
--
Rudy Velthuis [TeamB] rvelthuis.de/
"It is practically imposible to teach good programming to students that
have had a prior exposure to BASIC: as potential programmers they are
mentally mutilated beyond hope of regeneration." -- Edsger Dijkstra
 

Re:Re: Trie?

In article < XXXX@XXXXX.COM >,
Bob Gonder < XXXX@XXXXX.COM >wrote:
Quote
Not to cast aspersions, but I get very different results:
Now try it as a cpp project and notice the difference...
--
-David
Nihil curo de ista tua stulta superstitione.