473,406 Members | 2,273 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Representing a ulong as An Array of Bytes

I need to store a uint in an array of bytes. Doing it old fashioned
style works:

byte[] b=new byte[8];
ulong ul = 1;
for(int j=0; j<8; j++)
{
--- obviously I could (and did) optimize the code inside the loop
--- I just wanted to keep my example simple
b[7 - j] = (byte)((ul & bmask) >j*8);
bmask = bmask << 8;
}

It gives me exactly what I need:
b[0] = 0;
b[1] = 0;
(snip)
b[7] = 1;

I was trying to use MemoryStream and BinaryWriter and see how fast it
performs:

MemoryStream ms = new MemoryStream(16);
BinaryWriter br = new BinaryWriter(ms);

for(ulong i=1; i<3; i++)
{
br.Write(i);
}
byte[] b = ms.ToArray();

Unfortunately the order of bytes is not what I want:
b[0] = 1;
b[1] = 0;
b[2] = 0;
(snip)
b[7] = 0;

Is there any way to use canned classes like MemoryStream and
BinaryWriter and get the results that I got from my first snippet? The
reason I am asking is simple: canned classes might perform faster than
my homemade solution.

Aug 17 '06 #1
12 2760
Try the BitConverter class
http://msdn2.microsoft.com/en-us/library/d8z32tce.aspx should be the
overload you seek (for a ulong)

Cheers,

Greg Young
MVP - C# http://codebetter.com/blogs/gregyoung

<AK************@hotmail.COMwrote in message
news:11**********************@p79g2000cwp.googlegr oups.com...
>I need to store a uint in an array of bytes. Doing it old fashioned
style works:

byte[] b=new byte[8];
ulong ul = 1;
for(int j=0; j<8; j++)
{
--- obviously I could (and did) optimize the code inside the loop
--- I just wanted to keep my example simple
b[7 - j] = (byte)((ul & bmask) >j*8);
bmask = bmask << 8;
}

It gives me exactly what I need:
b[0] = 0;
b[1] = 0;
(snip)
b[7] = 1;

I was trying to use MemoryStream and BinaryWriter and see how fast it
performs:

MemoryStream ms = new MemoryStream(16);
BinaryWriter br = new BinaryWriter(ms);

for(ulong i=1; i<3; i++)
{
br.Write(i);
}
byte[] b = ms.ToArray();

Unfortunately the order of bytes is not what I want:
b[0] = 1;
b[1] = 0;
b[2] = 0;
(snip)
b[7] = 0;

Is there any way to use canned classes like MemoryStream and
BinaryWriter and get the results that I got from my first snippet? The
reason I am asking is simple: canned classes might perform faster than
my homemade solution.

Aug 17 '06 #2
Thank you Greg. I am comparing different ways to send a large array of
unsigned longs to SQL Server 2000. The solution needs to be very
performant. Among other alternatives, I am sending to the database an
image, as follows:

SqlCommand a = new SqlCommand("ImageTest", conn);
a.CommandType = System.Data.CommandType.StoredProcedure;
a.Parameters.Add(new SqlParameter("@image",
System.Data.SqlDbType.Image,2147483647));
-- b is an array of bytes
a.Parameters[0].Value = b;

My understanding is that BitConverter will create a new array of bytes
for every unsigned long, and I think that would be hard on the garbage
collector. My understanding is that most likely I will not notice that
in a short test on my local PC, but eventually in the production that
would cause a slowdown. So I estimate that in my situation it is better
to swap then bytes manually so that there are only 2 new objects as
opposed to 10001:

MemoryStream ms = new MemoryStream(80000);
BinaryWriter br = new BinaryWriter(ms);
for(ulong i=1; i<10001; i++)
{
br.Write(i);
}
byte[] b = ms.ToArray();
byte[] b1 = new byte[80000];
--- swap the bytes manually
for(k=0; k<80000; k+=8)
{
for(j=0; j<8; j++)
{
b1[k+7-j] = b[k+j];
}
}

Please correct me if I am wrong.

Aug 17 '06 #3
Or you could just use a BinaryWriter and a memory stream .. the binary
writer actually does this in a more effiicient way than you do..

reflector'ed source of write method.

public virtual void Write(long value)
{
this._buffer[0] = (byte) value;
this._buffer[1] = (byte) (value >8);
this._buffer[2] = (byte) (value >0x10);
this._buffer[3] = (byte) (value >0x18);
this._buffer[4] = (byte) (value >0x20);
this._buffer[5] = (byte) (value >40);
this._buffer[6] = (byte) (value >0x30);
this._buffer[7] = (byte) (value >0x38);
this.OutStream.Write(this._buffer, 0, 8);
}
Cheers,

Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung

<AK************@hotmail.COMwrote in message
news:11**********************@75g2000cwc.googlegro ups.com...
Thank you Greg. I am comparing different ways to send a large array of
unsigned longs to SQL Server 2000. The solution needs to be very
performant. Among other alternatives, I am sending to the database an
image, as follows:

SqlCommand a = new SqlCommand("ImageTest", conn);
a.CommandType = System.Data.CommandType.StoredProcedure;
a.Parameters.Add(new SqlParameter("@image",
System.Data.SqlDbType.Image,2147483647));
-- b is an array of bytes
a.Parameters[0].Value = b;

My understanding is that BitConverter will create a new array of bytes
for every unsigned long, and I think that would be hard on the garbage
collector. My understanding is that most likely I will not notice that
in a short test on my local PC, but eventually in the production that
would cause a slowdown. So I estimate that in my situation it is better
to swap then bytes manually so that there are only 2 new objects as
opposed to 10001:

MemoryStream ms = new MemoryStream(80000);
BinaryWriter br = new BinaryWriter(ms);
for(ulong i=1; i<10001; i++)
{
br.Write(i);
}
byte[] b = ms.ToArray();
byte[] b1 = new byte[80000];
--- swap the bytes manually
for(k=0; k<80000; k+=8)
{
for(j=0; j<8; j++)
{
b1[k+7-j] = b[k+j];
}
}

Please correct me if I am wrong.

Aug 17 '06 #4
<AK************@hotmail.COMwrote:
I need to store a uint in an array of bytes.
See http://www.pobox.com/~skeet/csharp/miscutil

It provides:
1) A BinaryWriter that lets you specify the endianness
2) A BitConverter that lets you specify the endianness *and convert
into an existing array*

They may well not be faster than your original solution, but I strongly
suspect that talking to SQL server is going to be a bottleneck long
before this is. What are your performance requirements for this section
of the code, and how do current solutions compare with it?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Aug 17 '06 #5
Or you could just use a BinaryWriter and a memory stream .. the binary
writer actually does this in a more effiicient way than you do..

reflector'ed source of write method.

public virtual void Write(long value)
{
this._buffer[0] = (byte) value;
this._buffer[1] = (byte) (value >8);
this._buffer[2] = (byte) (value >0x10);
this._buffer[3] = (byte) (value >0x18);
this._buffer[4] = (byte) (value >0x20);
this._buffer[5] = (byte) (value >40);
this._buffer[6] = (byte) (value >0x30);
this._buffer[7] = (byte) (value >0x38);
this.OutStream.Write(this._buffer, 0, 8);
}
Thanks Greg, this code snippet really helped. In fact, I don't see any
advantage of using a memory stream. It's so simple:

static byte[] UlongsToBytes(ulong[] ulongs)
{
int ifrom = ulongs.GetLowerBound(0);
int ito = ulongs.GetUpperBound(0);
int l = (ito - ifrom + 1)*8;
byte[] ret = new byte[l];
int retind = 0;
for(int i=ifrom; i<ito; i++)
{
ulong v = ulongs[i];
ret[retind++] = (byte) (v >0x38);
ret[retind++] = (byte) (v >0x30);
ret[retind++] = (byte) (v >40);
ret[retind++] = (byte) (v >0x20);
ret[retind++] = (byte) (v >0x18);
ret[retind++] = (byte) (v >0x10);
ret[retind++] = (byte) (v >8);
ret[retind++] = (byte) v;
}

return ret;
}

Am I missing something? Why should I use a memory stream?

Aug 17 '06 #6
>
See http://www.pobox.com/~skeet/csharp/miscutil

It provides:
1) A BinaryWriter that lets you specify the endianness
2) A BitConverter that lets you specify the endianness *and convert
into an existing array*

They may well not be faster than your original solution, but I strongly
suspect that talking to SQL server is going to be a bottleneck long
before this is. What are your performance requirements for this section
of the code, and how do current solutions compare with it?
Thanks Jon, reading the sources was very interesting. The performance
requirements are simple: it must work faster than the competitors'
solutions.

Aug 17 '06 #7
Well ...

1) the memory stream automatically will size itself ..
2) you can just use a BinaryWriter ... that code is reflector'ed from the
BinaryWriter class .. Why write it yourself?

Cheers,

Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung

<AK************@hotmail.COMwrote in message
news:11**********************@b28g2000cwb.googlegr oups.com...
>Or you could just use a BinaryWriter and a memory stream .. the binary
writer actually does this in a more effiicient way than you do..

reflector'ed source of write method.

public virtual void Write(long value)
{
this._buffer[0] = (byte) value;
this._buffer[1] = (byte) (value >8);
this._buffer[2] = (byte) (value >0x10);
this._buffer[3] = (byte) (value >0x18);
this._buffer[4] = (byte) (value >0x20);
this._buffer[5] = (byte) (value >40);
this._buffer[6] = (byte) (value >0x30);
this._buffer[7] = (byte) (value >0x38);
this.OutStream.Write(this._buffer, 0, 8);
}

Thanks Greg, this code snippet really helped. In fact, I don't see any
advantage of using a memory stream. It's so simple:

static byte[] UlongsToBytes(ulong[] ulongs)
{
int ifrom = ulongs.GetLowerBound(0);
int ito = ulongs.GetUpperBound(0);
int l = (ito - ifrom + 1)*8;
byte[] ret = new byte[l];
int retind = 0;
for(int i=ifrom; i<ito; i++)
{
ulong v = ulongs[i];
ret[retind++] = (byte) (v >0x38);
ret[retind++] = (byte) (v >0x30);
ret[retind++] = (byte) (v >40);
ret[retind++] = (byte) (v >0x20);
ret[retind++] = (byte) (v >0x18);
ret[retind++] = (byte) (v >0x10);
ret[retind++] = (byte) (v >8);
ret[retind++] = (byte) v;
}

return ret;
}

Am I missing something? Why should I use a memory stream?

Aug 17 '06 #8
<AK************@hotmail.COMwrote:
Thanks Jon, reading the sources was very interesting. The performance
requirements are simple: it must work faster than the competitors'
solutions.
Presumably that's an *overall* requirement though, not a requirement of
this particular piece of the code. Have you measured how much of the
time is spent converting ulongs to arrays of bytes?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Aug 18 '06 #9
Greg Young <dr*******************@hotmail.comwrote:
1) the memory stream automatically will size itself ..
2) you can just use a BinaryWriter ... that code is reflector'ed from the
BinaryWriter class .. Why write it yourself?
Check the differences between the code you posted and the version the
OP just posted - the endianness is different.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Aug 18 '06 #10
Right you are.
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Greg Young <dr*******************@hotmail.comwrote:
>1) the memory stream automatically will size itself ..
2) you can just use a BinaryWriter ... that code is reflector'ed from the
BinaryWriter class .. Why write it yourself?

Check the differences between the code you posted and the version the
OP just posted - the endianness is different.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Aug 18 '06 #11
>
Presumably that's an *overall* requirement though, not a requirement of
this particular piece of the code. Have you measured how much of the
time is spent converting ulongs to arrays of bytes?
Jon,

Your point is taken. You are correct - the time on the client side is
negligible either way.

Aug 18 '06 #12
Thanks Greg

Aug 18 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
5
by: alex | last post by:
how do i initialize an atl ULONG* variable? ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==---- http://www.newsfeed.com The #1 Newsgroup Service in the World!...
4
by: Bryan Parkoff | last post by:
I want to allocate pointer array into memory so pointer array contains ten pointers. It would be 4 bytes per pointer to be total 40 bytes. Looks like below for example. unsigned char* A = new...
6
by: Herrcho | last post by:
in K&R Chapter 6.3 it mentions two methods to calculate NKEYS. and points out the first one which is to terminate the list of initializers with a null pointer, then loop along keytab until the...
22
by: Wynand Winterbach | last post by:
I think every C programmer can relate to the frustrations that malloc allocated arrays bring. In particular, I've always found the fact that the size of an array must be stored separately to be a...
2
by: Nadav | last post by:
How can a UInt64 be converted to a byte ????
3
by: Nick | last post by:
I have found a class that compresses and uncompresses data but need some help with how to use part of it below is the deflate method which compresses the string that I pass in, this works OK. At...
9
by: Sanjib Biswas | last post by:
Could anyone point out to me the difference between ulong (C#) and UInt64/ULong (VB.Net)? I was under the impression that both are same. Below C# code works fine for a particular value of 'data'...
2
by: O.B. | last post by:
When using Marshal to copy data from a byte array to the structure below, only the first byte of the "other" array is getting copied from the original byte array. What do I need to specify to get...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.