Hey,
we are doing a very performance-critical system.
I need to profile the speed & size of each object , method calls & so.
I have got some profilers , but non measures the object's size.
Do you have any method , library , etc.. to measure the size of instances of the classes ?
Also anyone recommends a good performance measurement / profiler for .net ?
Thanks in advance
-
-
The .net runtime deliberately makes it difficult to find out that information on the basis that it would encourage people to write architecture-specific code. So officially the size of an object in memory is implementation specific. Baring the runtime using some whacky optimizations, it's a fair bet the object is the same size on any given architecture from run to run though.
For the microsoft .NET runtime, running on 32-bit x86, there is a two word overhead per heap-allocated object. One is just for the vtable pointer and the other for various things including garbage collection and thread synchronization. Then you have the fields. You can tell the runtime to lay an object out with it's fields in the order they are declared using an attribute. You can also specify a layout using attributes (for interop purposes mostly). If you don't specify any attributes, the runtime is free to rearrange fields as it sees fit. I'm not sure if it packs (for example) multiple byte fields into a word or not.
I'm not sure how important it is to know the size of the object in memory for performance tuning. I mean, as long as you let .NET do it's job, it'll pack it in the smallest space anyway. Unless you're planning to drop fields, there's not much tuning to do. However, if you're really keen you could download the Rotor (shared source CLI) source and look at that. -
Look at the Marshal.x functions and you might be able to get a better picture of the sizes of your objects.
I believe that there is a Marshal.SizeOf function (or something similar) that will tell you how much non managed memory your object will occupy.
Part of the "how big is it" question, is hidden from you, on purpose. Further, duplicate strings are only stored once in memory. -
Remon wrote:Hey,
we are doing a very performance-critical system.
I need to profile the speed & size of each object , method calls & so.
I have got some profilers , but non measures the object's size.
Do you have any method , library , etc.. to measure the size of instances of the classes ?
Also anyone recommends a good performance measurement / profiler for .net ?
Thanks in advance
is it Speed critical or Size critical ?
at what level ?
will it run on a device like an embeded system or a normal PC / server ?
in most cases I'd say write the app or a sample of the app and just see if it has a perf problem then look at what to tune.
due to GC and memory management trying to pin-down the size will be difficult at best and may not make it run any better.
things that tend to be the hogs and killers are the things that cause 2nd level GC events. or too many first level GC's
for example strings..... if you create and modify a lot of them you can consume a *LOT* of memory and have a lot of GC runs to slow you down.
sometimes you use StringBuilder() to fix that.
but any time you have boxing / unboxing going on you will incurr perf issues.
so look for that also.
-
Remon wrote:Hey, we are doing a very performance-critical system. I need to profile the speed & size of each object , method calls & so.
If you're so concerned about speed and peformance, you'd write the program in Assembly or even C/C++ (which is technically, more portable than MSIL). You write in languages compiled to MSIL for a bit of portability, but mainly for the RAD implications and excellent framework.
If you're looking for RAD and speed, I recommend you check out Delphi instead, but since you're asking about byte-wise size of object instances, you really want to be using C++.
-
I think if you want to get the size of a .net instance, you can always use sizeof or System.Runtime.InteropServices.Marshal.Sizeof(), although this two methods will return different values for Char type.
Sheva -
Hey,
I have already tried Marshal.SizeOf() , this gets the size of unmanaged objects. mine is a managed one.
When i try it , i get his error
Type 'Bla.BlaBla.BlaLogFile' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.
-
You should check out these 2 blog posts:
-
you still have not indicated the "domain of the problem" in regard to
how critical the "size" and the "speed" are.
this leaves a lot of room for bad guesses and wasted time and resources.
for example:
is this embeded?
is it machine to machine level operations ?
is it machine to human ?
is it "Human life critical" as in a person could die if it fails ?
is it more size constrained than speed or the opposite?
generally in most code you trade one for the other.
like taking a loop and runrolling it you may make some code faster by making it larger.
so often the "Fast" code is large and the "Small" code is slower.
but how much that matters depends on the use of it.
so I'd look at how it's used and then see what the constraints are and then decide how to impliment the code.
that's if the need to lock down the size and speed are that great.
even in most games you spend the most work in things like painting the screen, user input is generally a factor of x10 or x100 or x1000 slower than the screen draw.
so you could write the userinput in script as long as the drawing system was fast.
just one extreem example of what I am trying to get at. -
Hey figuerres,
The system is both size & performance critical.
System should Parse about 10 BILLION Lines / day , store them into business objects for later processing & correlation & store them into DB.
It should be a big servers farm for this, still we have to be VERY careful while implementing the system.
it's .NET based, That's why you can't compare it to games programming
.
It's Webservices & COM+ system. should recieves files, parse & do some business over it, then store everything (Results & lines into DB)
I want to measure the objects size in memory, how much this object takes & how much overhead it has , etc...
For example: We found that the normal System.String Class, it supports UNICODE, while we work only, so we can save 50% of the object size if we can use ASCII-only-support String class.
Actual String size is calculated as that following:
Size = 20 + (n/2)*4 Bytes
Where 20 is overhead, & n is the no of characters in the string.
One of my team got this by researching, but we can't find anything else about other types. so if you can help by providing a profiler or a reference on how to calculate the sizes it will be very appreciated.
Thank you for your time -
Remon wrote:Hey figuerres,
The system is both size & performance critical.
System should Parse about 10 BILLION Lines / day , store them into business objects for later processing & correlation & store them into DB.
It should be a big servers farm for this, still we have to be VERY careful while implementing the system.
it's .NET based, That's why you can't compare it to games programming
.
It's Webservices & COM+ system. should recieves files, parse & do some business over it, then store everything (Results & lines into DB)
I want to measure the objects size in memory, how much this object takes & how much overhead it has , etc...
For example: We found that the normal System.String Class, it supports UNICODE, while we work only, so we can save 50% of the object size if we can use ASCII-only-support String class.
Actual String size is calculated as that following:
Size = 20 + (n/2)^4 Bytes
Where 20 is overhead, & n is the no of characters in the string.
One of my team got this by researching, but we can't find anything else about other types. so if you can help by providing a profiler or a reference on how to calculate the sizes it will be very appreciated.
Thank you for your time
Ok so it sounds like you have some kind of EDI / TP thing to build then...
while I do not have a system in the billions of lines of parsing I do have a working app that does a good volume of web services traffic that goes to a sql db.
my system has 2 servers, each is an "off the shelf" DELL server.
we run about 6-8k orders a day plus other related traffic (auth, void,inq and so on)
the "front end" web server runs the ws on one virtual and 2 other web apps on others.
I have never seen ram go over about 600 megs in use.
now I think you have a lot more string management then my app and it sounds like a higher number of Transactions per day.
I think I would build a "Mockup" of the main logic and run it and just see what happens to memory use over a good time span.
I hope this is not beeing to basic but you do know that .net uses a stratigey of allocating ram from the OS in advance in large blocks and not giing it back unless it has to right ??
so if you run a large app it can grab what looks like a huge amount of ram and hold it till the app shuts down.
inside it's moving stuff around and keeping from asking for more os memory till it has to.
any profiler should show you how active GC 0,1 are and what kind of objects are scavanged (strings, other types)
there are some documents and stuff on msdn about what kind of pattern you want to see but as I recall it's mostly GC0 with a few things living longer and not scavenged till the end.
stuff that just hits GC1 and then dies is the "Worst case" as I recall for the .Net GC system. -
Remon wrote:
Actual String size is calculated as that following:
Size = 20 + (n/2)*4 Bytes
Where 20 is overhead, & n is the no of characters in the string.
Youch 20 byte overhead? I am sure that is an acceptable ease-of-use/space trade-off, but if you are really trying to trim space, why use strings? Use byte[] and save yourself some space?
-
figuerres wrote:
now I think you have a lot more string management then my app and it sounds like a higher number of Transactions per day.
I think I would build a "Mockup" of the main logic and run it and just see what happens to memory use over a good time span.
True. System stores tons of strings.
I have tried to parse about 150K lines. The system was initially 10 Megs, Expanded to about 160 Megs after parsing (Note: array of parsed objects exists into memory now).
Most properties are strings.
figuerres wrote:
I hope this is not beeing to basic but you do know that .net uses a stratigey of allocating ram from the OS in advance in large blocks and not giing it back unless it has to right ??
Actually no
this is the first time to hear that. However, as i said above, the program got more memory while parsing (10M to 150 M)
figuerres wrote:
any profiler should show you how active GC 0,1 are and what kind of objects are scavanged (strings, other types)
there are some documents and stuff on msdn about what kind of pattern you want to see but as I recall it's mostly GC0 with a few things living longer and not scavenged till the end.
stuff that just hits GC1 and then dies is the "Worst case" as I recall for the .Net GC system.
can u recommend a profiler ?
also. can i have a string supports ASCII only ? & How ?
-
Remon wrote:

figuerres wrote:
now I think you have a lot more string management then my app and it sounds like a higher number of Transactions per day.
I think I would build a "Mockup" of the main logic and run it and just see what happens to memory use over a good time span.
True. System stores tons of strings.
I have tried to parse about 150K lines. The system was initially 10 Megs, Expanded to about 160 Megs after parsing (Note: array of parsed objects exists into memory now).
Most properties are strings.

figuerres wrote:
I hope this is not beeing to basic but you do know that .net uses a stratigey of allocating ram from the OS in advance in large blocks and not giing it back unless it has to right ??
Actually no
this is the first time to hear that. However, as i said above, the program got more memory while parsing (10M to 150 M)

figuerres wrote:
any profiler should show you how active GC 0,1 are and what kind of objects are scavanged (strings, other types)
there are some documents and stuff on msdn about what kind of pattern you want to see but as I recall it's mostly GC0 with a few things living longer and not scavenged till the end.
stuff that just hits GC1 and then dies is the "Worst case" as I recall for the .Net GC system.
can u recommend a profiler ?
also. can i have a string supports ASCII only ? & How ?
yeah, .net looks for a "working set" it will grow a process till it seems to have enoguh ram, depending on the runtime it uses different logic on GC events also....
see on a server it uses one set of dll's and on a client it uses a different set. clients tend to run 1 app and want max speed.
servers tend to need to balance things. also on a client it may not GC till the app closes if it can. on a server it will GC based on a "hartbeat" to keep multiple processes balanced.
I have not done any profiling in a while ...
you may want to look at:
http://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&DisplayLang=en -
also if you do have a lot of string stuff see if string builder helps.
if you are not aware of this it may make a huge difference:
in .Net strings are "IMUTEABLE" wich means that
string a
string b
for loop x 1,000
a=i.tostring()
b=b+","+a;
will create over 1,000 strings in memory that will need to be GC'ed
if you do:
a = b + a
then you are creating
a_old
a_new
each a different string, with a refering to a_new and when a gc happens a_old can be droped if no other ref's point to it.
but if you have say
foo = a
a = b + a
then a_old can not be gc in all cases and may live till later.
StringBuilder
will allow you to work with a buffer and not create as many strings.
good use of that can reduce allocation presssure by huge amounts.
for example if you currently are not using it you may see something like:
old 10 meg - end at 160 megs
new 10 meg - end at 20 megs
just as a guess - see what your code looks like and are you using strings where you can use string builder to cut back on allocating
100,000 or more temp-strings.
-
also a general rule I got from others and had been true is this:
write the app with good coding practice and then test it.
if you see a problem with perf or memory profile and find the problem.
in many cases 90% or more of the app's code will not matter.
you will find 1 to 5% of the code taking up 50% of the time or memory and you can then target that and tune it.
if you spend to much time trying to get too perfect you will actually waste a lot of time fixing code that was not a problem in the first place.
so let the tools tell you where to look.
just write good code in general and most of it will be just fine
also the size and memory is a moving target.
the Jit will make different code based on x86/ x64 and client or server and could change if there is a service pack that updates the Jitter.
so even if you find the size today on an x86 32 bit pc if you run it on an x64 bit server the size will be different !
-
figuerres wrote:
StringBuilder
will allow you to work with a buffer and not create as many strings.
good use of that can reduce allocation presssure by huge amounts.
for example if you currently are not using it you may see something like:
old 10 meg - end at 160 megs
new 10 meg - end at 20 megs
just as a guess - see what your code looks like and are you using strings where you can use string builder to cut back on allocating
100,000 or more temp-strings.
public void Parse(ref string Line)
{
int iAttributeCursor = 0, iAttributesCount;
string[] arrAttributes = Line.Split('\t');
//Get the Severity ( First Attribute of the Line )
_Priority = int.Parse(arrAttributes[iAttributeCursor++]);
//Get the Facility by Shifting the Priority right by 3 ( dividing by 8 )
_Facility = _Priority >> 3;
//Get the Severity by bitwise Anding with 7
//"3 ones in the least significant 3 bits" = getting the modulus of priority divided by 8
_Severity = _Priority & 7;
//Get the timestamp of the event ( Convert from Ticks )
_Timestamp = new DateTime(long.Parse(arrAttributes[iAttributeCursor++]));
//Get the device name which populated the event
_DeviceName = arrAttributes[iAttributeCursor++];
}
that's a sample for the code i ve written.
StringBuilder won't do good, because it's not FEW large strings, they are LOTS of SHORT strings.
I have tried somthing like: _DeviceName = (string)arrAttributes[iAttributeCursor++].Clone(); just to make sure the the arrAttributes will be GCed.
but this haven't made any difference & it will affect the speed of the system (boxing & unboxing)
I will try writing a string class based over bytes (supports ASCII only), got any ideas ? -
Remon wrote:I will try writing a string class based over bytes (supports ASCII only), got any ideas ?
Why not write a stream so you are never reading more than a handful of bytes and convert them on the fly as you return them - especially if you know the separator char and the values are all ints .. you code might then look like this ...
_Priority = stream.NextInt()
_Facility = _Priority >> 3;
_Severity = _Priority & 7;
_Timestamp = new DateTime( long.Parse( stream.NextLong() );
_DeviceName = stream.NextString();
You could then do whatever conversion you need in the specific methods based on a buffer of the last few bytes before the last separator?
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.