[Mono-list] string/buffer allocation speed issue
tomjohnson3
tomjohnson3 at gmail.com
Fri Jan 23 10:32:23 EST 2009
hi,
i'm attempting to write a fast scanner/parser in C#. basically, i receive a
byte buffer from a stream, then i copy it to a char array while manipulating
the bytes in the process.
in order to make this fast, i'm processing the buffers in an 'unsafe' block
and 'fixing' the byte and char arrays in order to do pointer arithmetic
directly on the buffers.
using VS.NET on windows xp, i wrote a simple console program (called
Scratch.exe) to test out the basics of this approach and i came across a
performance issue when running the same program using mono 2.2 - the speed
in which strings and char buffers are created.
the main code snippet that i used for the two test runs is below:
int length = 1024;
byte[] bytes = new byte[length];
bytes[length - 1] = 0;
char[] chars = new char[length + 1];
int iterations = 500000;
for (int i = 0; i < iterations; i++)
{
// NOTE: uncomment this line for the second test...
//chars = new char[length + 1];
unsafe
{
fixed (byte* pFixedBytes = bytes)
fixed (char* pFixedChars = chars)
{
byte* pByte = pFixedBytes;
char* pChar = pFixedChars;
while ((*pChar++ = (char)(*pByte++)) != 0)
{
// NOTE: further processing will go here...
}
*pChar = (char)0;
string result = new string(pChar);
// NOTE: the result string will be used elsewhere in the future; ignored
for tests...
}
}
}
the performance difference (caused by the string and buffer allocation) when
running this simple program on windows xp using microsoft vs. mono 2.2 is
pretty big...and i was hoping there's something i can do to reduce or
eliminate the difference.
here are the performance numbers for test 1 (allocating the char array once,
upfront):
microsoft/windows xp: duration: 0.047sec; rate: 10638298/sec
mono 2.2/windows xp: duration: 0.234sec; rate: 2136752/sec
for test 1, the mono 2.2 default profiler results show:
Time(ms) Count P/call(ms) Method name
[snip]
########################
1488.000 500000 0.003 System.String::.ctor(char*)
Callers (with count) that contribute at least for 1%:
500000 100 % Scratch.Program::Main(string[])
########################
991.000 500000 0.002 System.String::CreateString(char*)
Callers (with count) that contribute at least for 1%:
500000 100 % System.String::.ctor(char*)
########################
454.000 500830 0.001 System.String::InternalAllocateStr(int)
Callers (with count) that contribute at least for 1%:
500000 99 % System.String::CreateString(char*)
[snip]
here are the performance numbers for test 2 (allocating a new char array in
each pass of the outer loop):
microsoft/windows xp: duration: 0.531sec; rate: 941620/sec
mono 2.2/windows xp: duration: 6.131sec; rate: 81553/sec
for test 2, the mono 2.2 default profiler results show:
Time(ms) Count P/call(ms) Method name
[snip]
########################
6294.000 500244 0.013
System.Object::__icall_wrapper_mono_array_new_specific(intptr,int)
Callers (with count) that contribute at least for 1%:
500002 99 % Scratch.Program::Main(string[])
########################
1510.000 500000 0.003 System.String::.ctor(char*)
Callers (with count) that contribute at least for 1%:
500000 100 % Scratch.Program::Main(string[])
########################
1041.000 500000 0.002 System.String::CreateString(char*)
Callers (with count) that contribute at least for 1%:
500000 100 % System.String::.ctor(char*)
########################
482.000 500830 0.001 System.String::InternalAllocateStr(int)
Callers (with count) that contribute at least for 1%:
500000 99 % System.String::CreateString(char*)
[snip]
any advice on how to eliminate these differences? i could pre-allocate a
'buffer pool' to reduce or eliminate the allocation of the char buffer (in
test 2) - but i don't really want to resort to this if i don't have to.
also, is there a way to make string allocation (test 1 and test 2) faster? i
can't seem to find a work-around for this issue. or should this code run
faster under linux using mono 2.2 (i.e., is mono 2.2 tuned for linux more
than windows)? (i'm going to run this test on a couple of different
systems.)
one final question: i also tried a third test where i have this code snippet
running on its own thread - with one thread per core (i have a dual-core
processor on my laptop). the performance difference using mono 2.2 between a
single-threaded and a multi-threaded programs was minimal...but using
microsoft, it was about double the performance. (also, mono 2.2 wasn't using
the full 100% of the CPU, while microsoft was able to, on this simple test.)
i'll gather some more info about this issue, but is there a reason why
string/buffer allocation in a multi-threaded program would not scale
linearly up to the number of cores in a processor?
i'd be happy to dig into code or donate my time to help fix this issue (if
it is an issue)...so, if someone could help to direct me to the right place,
i'd appreciate it!
thanks for the help!
tom
--
View this message in context: http://www.nabble.com/string-buffer-allocation-speed-issue-tp21626581p21626581.html
Sent from the Mono - General mailing list archive at Nabble.com.
More information about the Mono-list
mailing list