Big-endian long <--> byte[8] conversion

M

Marc Gravell

Short version: is it possible to control the endian-ness of BitConverter? -
or are there any /framework/ methods like
BigEndianBitConverter.GetBytes(long) and .ToInt64()?
(I am not after equivalent code; I already have that)

===

Background:
I'm dealing with Sql-Server timestamp fields [which are equivalent to the
binary(8) sql data-type]; in some circumstances (e.g. OpenXml) they need to
be representated using the bigint sql-datatype (equiv. to the c# long); the
sql cast between bigint and binary(8) is (as far as I can tell) big-endian.

Now; when I get the timestamp (as a byte[]) from the database in C#, it also
appears to be big-endian; I want to convert this to a long, so that I can
use it in an xml structure for OpenXml later on (for a complex block
update); for efficiency (and simplicity) I had hoped to use BitConverter,
but this (on my environment, at least) is little-endian.

Obviously it is fairly simple to code this translation (have done it; it
works fine - this is not the problem), but is there a framework way of doing
this conversion? I realise that simple byte-shifts and binary-ORs work very
efficiently, but the code would be used a fair bit, and often the framework
wrappers can cheat and do things even more frugally... (and yes: this is
probably "premature optimisation", but the question stands...)

Or am I being too hopeful?

Marc
 
J

Jon Skeet [C# MVP]

Marc said:
Short version: is it possible to control the endian-ness of BitConverter? -
or are there any /framework/ methods like
BigEndianBitConverter.GetBytes(long) and .ToInt64()?
(I am not after equivalent code; I already have that)

No, I don't believe there's anything in the framework.

I have a library to provide equivalent code in a nicely wrapped up way,
however :)

http://www.pobox.com/~skeet/csharp/miscutil

Jon
 
M

Marc Gravell

Kinda confirms what I suspected, cheers Jon.

Handy wrapper, btw; if I need any more conversions I may well use those
classes. For now, my "long only" version is sufficient and less complex -
the only real coding difference is that I am using a "--" foreach loop (in
what you have called FromBytes) to make the buffer lookup nominally quicker,
plus you reminded me to use "unchecked", which will help... I'm also
currently checking BitConverter.IsLittleEndian to decide whether to use the
CPU's native translation, which is possibly overkill (and I'd need an IA64
to properly test it...).

Cheers,

Marc
 
J

Jon Skeet [C# MVP]

Marc said:
Kinda confirms what I suspected, cheers Jon.

Handy wrapper, btw; if I need any more conversions I may well use those
classes. For now, my "long only" version is sufficient and less complex -
the only real coding difference is that I am using a "--" foreach loop (in
what you have called FromBytes) to make the buffer lookup nominally quicker,
plus you reminded me to use "unchecked", which will help... I'm also
currently checking BitConverter.IsLittleEndian to decide whether to use the
CPU's native translation, which is possibly overkill (and I'd need an IA64
to properly test it...).

Well, you don't need an IA64 to compare the speed of your own routine
to the speed of BitConverter if you just ignore the results. I strongly
suspect you'll find that it's actually not significantly faster to use
BitConverter - in which case make the code as simple as possible and
ignore BitConverter entirely :)

Jon
 
M

Marc Gravell

By my tests, 46.9ms/million (BitConverter) vs 93.8ms/million (my code minus
BitConverter check/usage) on the same h/w (release build, no IDE); it isn't
exactly order-of-magnitude bigger, so you are right: keep it simple and
ditch BitConverter for this particular case.

Interesting little exercise (or maybe I should get out more ;-p)

Marc
 
J

Jon Skeet [C# MVP]

Marc said:
By my tests, 46.9ms/million (BitConverter) vs 93.8ms/million (my code minus
BitConverter check/usage) on the same h/w (release build, no IDE); it isn't
exactly order-of-magnitude bigger, so you are right: keep it simple and
ditch BitConverter for this particular case.

Interesting little exercise (or maybe I should get out more ;-p)

One thing it may be interesting to try: turn your array into a fixed
pointer, and index it that way. You may find that accounts for the
difference - not that it's that huge anyway, as you've said.

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top