473,387 Members | 1,757 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,387 software developers and data experts.

Speed Freaks & Bit Fiddlers: Can you make this go faster?

Can someone show me how to speed this up?

1. Whats the fastest way for Unsafe C#?
2. What the fastest way for Safe C#?

public static Int64 ToInt64(Int32 low, Int32 high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);

Byte[] bytes = new Byte[8];

Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);

return BitConverter.ToInt64(bytes, 0);
}

Thanks.

Russell Mangel
Las Vegas, NV

PS
The winner will receive keys for a Mercedes Benz.

Dec 30 '06 #1
9 2028
How about:
public static Int64 ToInt64(Int32 low, Int32 high)
{
Int64 x = high;
x <<= 32;
x = x | low;
}
Russell Mangel wrote:
Can someone show me how to speed this up?

1. Whats the fastest way for Unsafe C#?
2. What the fastest way for Safe C#?

public static Int64 ToInt64(Int32 low, Int32 high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);

Byte[] bytes = new Byte[8];

Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);

return BitConverter.ToInt64(bytes, 0);
}

Thanks.

Russell Mangel
Las Vegas, NV

PS
The winner will receive keys for a Mercedes Benz.
Dec 30 '06 #2
Geee...

Thats slow ;)

Try this

public static Int64 FastToInt64(Int32 low, Int32 high)

{

return ((Int64)(high) << 32) + low;

}

"Russell Mangel" <ru*****@tymer.netwrote in message
news:O2**************@TK2MSFTNGP03.phx.gbl...
Can someone show me how to speed this up?

1. Whats the fastest way for Unsafe C#?
2. What the fastest way for Safe C#?

public static Int64 ToInt64(Int32 low, Int32 high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);

Byte[] bytes = new Byte[8];

Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);

return BitConverter.ToInt64(bytes, 0);
}

Thanks.

Russell Mangel
Las Vegas, NV

PS
The winner will receive keys for a Mercedes Benz.
Dec 30 '06 #3
Or, in one line (safe C#):

return (Int64)(((UInt64)high << 32) | (UInt32)low);

Tom Dacon
Dacon Software Consulting
"Russell Mangel" <ru*****@tymer.netwrote in message
news:O2**************@TK2MSFTNGP03.phx.gbl...
Can someone show me how to speed this up?

1. Whats the fastest way for Unsafe C#?
2. What the fastest way for Safe C#?

public static Int64 ToInt64(Int32 low, Int32 high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);

Byte[] bytes = new Byte[8];

Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);

return BitConverter.ToInt64(bytes, 0);
}

Thanks.

Russell Mangel
Las Vegas, NV

PS
The winner will receive keys for a Mercedes Benz.

Dec 30 '06 #4
In article news:11**********************@n51g2000cwc.googlegr oups.com,
Tim Clark wrote:
How about:
public static Int64 ToInt64(Int32 low, Int32 high)
{
Int64 x = high;
x <<= 32;
x = x | low;
}
Quite, except that Russell's definition of 'low' and 'high' may be
surprising... The output that I get, with the first line from Russell's
function, I get:

low & high = result
11223344 & aabbccdd = 11223344aabbccdd
11223344 & aabbccdd = 11223343aabbccdd
11223344 & aabbccdd = 11223343aabbccdd

So low is (Intel-wise) high, and high low... :-)

Out of interest I created two slighty different methods of doing it:
public static Int64 Alan1_ToInt64(Int32 low, Int32 high)
{
const Int64 Bit32 = 0x100000000;
System.Diagnostics.Debug.Assert(Bit32 == (0x1L + UInt32.MaxValue));
System.Diagnostics.Debug.Assert(Bit32 == (0x1L << 32));
Int64 result = high + Bit32 * low;
return result;
}

public static Int64 Alan2_ToInt64(Int32 low, Int32 high)
{
Int64 result = high | ((Int64)low << 32);
return result;
}

And on inspecting the disassembly of both, assuming my unqualified
reading of x86 assembler is correct, both are JITted to a x86 shift
operation... So chose either depending on which is more
'understandable'.

Then I re-looked at my results and saw in the latter two lines: 11, 22,
33, 43!!!! WTF?
The I inputted all the functions that have been posted here so far, and
I get:

low & high = result
11223344 & aabbccdd = 11223344aabbccdd
11223344 & aabbccdd = 11223343aabbccdd
11223344 & aabbccdd = 11223343aabbccdd
11223344 & aabbccdd = aabbccdd11223344
11223344 & aabbccdd = aabbccdd11223344
11223344 & aabbccdd = aabbccdd11223344

low & high = result
aabbccdd & 11223344 = aabbccdd11223344
aabbccdd & 11223344 = aabbccdd11223344
aabbccdd & 11223344 = aabbccdd11223344
aabbccdd & 11223344 = ffffffffaabbccdd
aabbccdd & 11223344 = ffffffffaabbccdd
aabbccdd & 11223344 = 11223343aabbccdd

!!! It's past my bedtime, so I leave it for someone else to explain...
Unless I've got a buggy CPU, and only I get this behaviour. I haven't
gone back an re-inspected the assembler for instance.

The code it thus:
{
public void DoIt()
{
const Int32 low = 0x11223344, high =
unchecked((Int32)0xaabbccdd);
DoItWith(low, high);
const Int32 high2 = 0x11223344, low2 =
unchecked((Int32)0xaabbccdd);
DoItWith(low2, high2);
}

private static void DoItWith(Int32 low, Int32 high)
{
Console.WriteLine("{0,8} & {1,8} = {2}", "low", "high",
"result");
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
RussellsOriginal_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
Alan1_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
Alan2_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
TimClark_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
TimClark_ToInt64(low, high));
Console.WriteLine("{0:x} & {1:x} = {2:x}", low, high,
rdrunner_FastToInt64(low, high));
}

public static Int64 Alan1_ToInt64(Int32 low, Int32 high)
{
const Int64 Bit32 = 0x100000000;
System.Diagnostics.Debug.Assert(Bit32 == (0x1L +
UInt32.MaxValue));
System.Diagnostics.Debug.Assert(Bit32 == (0x1L << 32));
Int64 result = high + Bit32 * low;
return result;
}

public static Int64 Alan2_ToInt64(Int32 low, Int32 high)
{
Int64 result = high + ((Int64)low << 32);
return result;
}

public static Int64 TimClark_ToInt64(Int32 low, Int32 high)
{
Int64 x = high;
x <<= 32;
// Warning: Bitwise-or operator used on a sign-extended
operand; consider casting to a smaller unsigned type first
x = x | low;
return x;
}

public static Int64 rdrunner_FastToInt64(Int32 low, Int32 high)
{
return ((Int64)(high) << 32) + low;
}

public static Int64 TomDacon_ToInt64(Int32 low, Int32 high)
{
return (Int64)(((UInt64)high << 32) | (UInt32)low);
}

public static Int64 RussellsOriginal_ToInt64(Int32 low, Int32
high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);

Byte[] bytes = new Byte[8];

Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);

return BitConverter.ToInt64(bytes, 0);
}

}

Alan
Russell Mangel wrote:
>Can someone show me how to speed this up?

1. Whats the fastest way for Unsafe C#?
2. What the fastest way for Safe C#?

public static Int64 ToInt64(Int32 low, Int32 high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);

Byte[] bytes = new Byte[8];

Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);

return BitConverter.ToInt64(bytes, 0);
}

Thanks.

Russell Mangel
Las Vegas, NV

PS
The winner will receive keys for a Mercedes Benz.
--
Alan J. McFarlane
http://www.alanjmcf.me.uk/
Please follow-up in the newsgroup for the benefit of all.

Dec 30 '06 #5
In article news:45**********************@ptn-nntp-reader02.plus.net,
Alan J. McFarlane wrote:
In article news:11**********************@n51g2000cwc.googlegr oups.com,
Tim Clark wrote:
[...]
public static Int64 Alan2_ToInt64(Int32 low, Int32 high)
{
Int64 result = high | ((Int64)low << 32);
Actually I was using a + rather than a | there.
return result;
}
[...]

Dec 30 '06 #6
On Sat, 30 Dec 2006 13:39:30 -0800, "Russell Mangel"
<ru*****@tymer.netwrote:
>Can someone show me how to speed this up?

1. Whats the fastest way for Unsafe C#?
2. What the fastest way for Safe C#?

public static Int64 ToInt64(Int32 low, Int32 high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);

Byte[] bytes = new Byte[8];

Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);

return BitConverter.ToInt64(bytes, 0);
}

Thanks.

Russell Mangel
Las Vegas, NV

PS
The winner will receive keys for a Mercedes Benz.
I have some good news and some bad news. Your method can be speeded
up but all the methods I tried, including yours, come up with the
wrong answer!

The results from the program below look like:
ToInt64A() had 50000 errors and took 1635 ticks on average.
ToInt64B() had 50000 errors and took 190 ticks on average.
ToInt64C() had 50000 errors and took 232 ticks on average.
ToInt64D() had 50000 errors and took 163 ticks on average.
ToInt64E() had 50000 errors and took 145 ticks on average.

where ToInt64A() is your method and B to E are alternative methods.

Running with one repetition and showing errors gives:
ToInt32A: result -53023518752769 != 9223372036854763462 expected
ToInt64A() had 1 errors and took 41386216 ticks on average.
ToInt32B: result 9223372032559796166 != 9223372036854763462 expected
ToInt64B() had 1 errors and took 1436216 ticks on average.
ToInt32C: result 9223372028264828870 != 9223372036854763462 expected
ToInt64C() had 1 errors and took 1839352 ticks on average.
ToInt32D: result 9223372032559796166 != 9223372036854763462 expected
ToInt64D() had 1 errors and took 1245720 ticks on average.
ToInt32E: result 9223372032559796166 != 9223372036854763462 expected
ToInt64E() had 1 errors and took 1245144 ticks on average.

your method appears to have a problem with signs. I have not been
able to track down the problems with the other methods in the short
time I have been looking.

The code I was using is below, perhaps someone else can find the
problem with the different methods (careful with line wrapping).

rossum

/////// Code //////////

public static Int64 ToInt64A(Int32 low, Int32 high) {
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);

Byte[] bytes = new Byte[8];
Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);

return BitConverter.ToInt64(bytes, 0);
}

public static Int64 ToInt64B(Int32 low, Int32 high) {
const Int64 shift = (Int64)UInt32.MaxValue + 1;
return high * shift + low;
}

public static Int64 ToInt64C(Int32 low, Int32 high) {
return 2 * Math.BigMul(high, Int32.MaxValue) + 2 * high + low;
}

public static Int64 ToInt64D(Int32 low, Int32 high) {
Int64 result = high;
return (result << 32) + low;
}

public static Int64 ToInt64E(Int32 low, Int32 high) {
return ((Int64)high << 32) + low;
}

public delegate Int64 ToInt64(Int32 lo, Int32 hi);

static void Main() {
//const int limit = 1;
const int limit = 50000;

ToInt64[] converters = new ToInt64[5];
converters[0] = ToInt64A;
converters[1] = ToInt64B;
converters[2] = ToInt64C;
converters[3] = ToInt64D;
converters[4] = ToInt64E;

Stopwatch timer = new Stopwatch();

char name = 'A';
Int64 expected = Int64.MaxValue - 12345;
Int32 lo = (Int32)(expected & 0xFFFFFFFFL);
Int32 hi = (Int32)(expected >32);
Int64 result;
int errorCount;
foreach (ToInt64 TI64 in converters) {
errorCount = 0;
timer.Reset();
timer.Start();
for (int i = 0; i < limit; ++i) {
result = TI64(lo, hi);
if (result != expected) {
++errorCount;
//Console.WriteLine("ToInt32{0}: result {1} != {2}
expected", name, result, expected);
}
}
timer.Stop();
Console.WriteLine("ToInt64{0}() had {1} errors and took
{2} ticks on average.",
name, errorCount, timer.ElapsedTicks / limit);
++name;
}
Console.Write("Press [Enter] to continue... ");
Console.ReadLine();
} // end Main()

///////////////////////

Dec 30 '06 #7
public static Int64 ToInt64F(Int32 low, Int32 high)
{
return (((Int64)high) << 32) | (UInt32)low;
}
Dec 31 '06 #8
Theneolab wrote:
public static Int64 ToInt64F(Int32 low, Int32 high)
{
return (((Int64)high) << 32) | (UInt32)low;
}
Looking back Tom beat me to it.
Dec 31 '06 #9
Russell Mangel wrote:
Can someone show me how to speed this up?

1. Whats the fastest way for Unsafe C#?
2. What the fastest way for Safe C#?

public static Int64 ToInt64(Int32 low, Int32 high)
{
Byte[] lowBytes = BitConverter.GetBytes(low);
Byte[] highBytes = BitConverter.GetBytes(high);

Byte[] bytes = new Byte[8];

Array.Copy(lowBytes, 0, bytes, 4, 4);
Array.Copy(highBytes, 0, bytes, 0, 4);

return BitConverter.ToInt64(bytes, 0);
}
Some experiments indicates that there are no faster
methods than the shift/arithmetic code.

See code below.

Arne

using System;
using System.Runtime.InteropServices;

namespace E
{
[StructLayout(LayoutKind.Explicit)]
internal struct IntLong
{
[FieldOffset(0)] public int lowintval;
[FieldOffset(4)] public int highintval;
[FieldOffset(0)] public long longval;
}
public class MainClass
{
public static long ToInt64_Bytes(int high, int low)
{
byte[] highBytes = BitConverter.GetBytes(high);
byte[] lowBytes = BitConverter.GetBytes(low);
byte[] bytes = new Byte[8];
Array.Copy(highBytes, 0, bytes, 4, 4);
Array.Copy(lowBytes, 0, bytes, 0, 4);
return BitConverter.ToInt64(bytes, 0);
}
public static long ToInt64_Arith(int high, int low)
{
return high * 0x100000000L + (uint)low;
}
public static long ToInt64_Shift(int high, int low)
{
return (((long)high)<<32) | (uint)low;
}
private static IntLong cvt;
public static long ToInt64_Union(int high, int low)
{
cvt.highintval = high;
cvt.lowintval = low;
return cvt.longval;
}
public unsafe static long ToInt64_Pointer(int high, int low)
{
long res;
*(((int *)&res)+1) = high;
*((int *)&res) = low;
return res;
}
private const int N = 200000000;
public static void Main(string[] args)
{
Random rng = new Random();
for(int i = 0; i < 1000; i++)
{
byte[] b = new byte[8];
rng.NextBytes(b);
long v = BitConverter.ToInt64(b, 0);
int vhigh = (int)(v >32);
int vlow = (int)v;
long v2 = ToInt64_Bytes(vhigh, vlow);
if(v2 != v)
{
Console.WriteLine("Bytes: " + v + " -" + v2);
}
long v3 = ToInt64_Arith(vhigh, vlow);
if(v3 != v)
{
Console.WriteLine("Arith: " + v + " -" + v3);
}
long v4 = ToInt64_Shift(vhigh, vlow);
if(v4 != v)
{
Console.WriteLine("Shift: " + v + " -" + v4);
}
long v5 = ToInt64_Union(vhigh, vlow);
if(v5 != v)
{
Console.WriteLine("Union: " + v + " -" + v5);
}
long v6 = ToInt64_Pointer(vhigh, vlow);
if(v6 != v)
{
Console.WriteLine("Pointer: " + v + " -" + v6);
}
}
DateTime t1 = DateTime.Now;
for(int i = 0; i < N; i++)
{
ToInt64_Bytes(12345,67890);
}
DateTime t2 = DateTime.Now;
Console.WriteLine("Bytes: " + (t2 - t1).TotalSeconds);
DateTime t3 = DateTime.Now;
for(int i = 0; i < N; i++)
{
ToInt64_Arith(12345,67890);
}
DateTime t4 = DateTime.Now;
Console.WriteLine("Arith: " + (t4 - t3).TotalSeconds);
DateTime t5 = DateTime.Now;
for(int i = 0; i < N; i++)
{
ToInt64_Shift(12345,67890);
}
DateTime t6 = DateTime.Now;
Console.WriteLine("Shift: " + (t6 - t5).TotalSeconds);
DateTime t7 = DateTime.Now;
for(int i = 0; i < N; i++)
{
ToInt64_Union(12345,67890);
}
DateTime t8 = DateTime.Now;
Console.WriteLine("Union: " + (t8 - t7).TotalSeconds);
DateTime t9 = DateTime.Now;
for(int i = 0; i < N; i++)
{
ToInt64_Pointer(12345,67890);
}
DateTime t10 = DateTime.Now;
Console.WriteLine("Pointer: " + (t10 - t9).TotalSeconds);
Console.ReadLine();
}
}
}
Dec 31 '06 #10

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

Similar topics

34
by: Jacek Generowicz | last post by:
I have a program in which I make very good use of a memoizer: def memoize(callable): cache = {} def proxy(*args): try: return cache except KeyError: return cache.setdefault(args,...
29
by: Bart Nessux | last post by:
Just fooling around this weekend. Wrote and timed programs in C, Perl and Python. Each Program counts to 1,000,000 and prints each number to the console as it counts. I was a bit surprised. I'm not...
28
by: Maboroshi | last post by:
Hi I am fairly new to programming but not as such that I am a total beginner From what I understand C and C++ are faster languages than Python. Is this because of Pythons ability to operate on...
3
by: I.V. Aprameya Rao | last post by:
Hi I have to implement a flat file dbms. The basic condition is that relations will be given in files and i will have to run certain select project join queries on those relations. Can...
7
by: YAZ | last post by:
Hello, I have a dll which do some number crunching. Performances (execution speed) are very important in my application. I use VC6 to compile the DLL. A friend of mine told me that in Visual...
11
by: Jim Lewis | last post by:
Has anyone found a good link on exactly how to speed up code using pyrex? I found various info but the focus is usually not on code speedup.
5
by: pt | last post by:
Hi, i am wonderng what is faster according to accessing speed to read these data structure from the disk in c/c++ including alignment handling if we access it on little endian system 32 bits...
19
by: llothar | last post by:
I must say i didn't expect this. I just did some measures on FreeBSD 6.2 with gcc 3.4.6 and there is absolutely no significant difference between 32 and 64 bit mode - neither in compilation speed,...
47
by: Mike Williams | last post by:
I'm trying to decide whether or not I need to move to a different development tool and I'm told that VB6 code, when well written, can be ten times faster than vb.net, but that if its badly written...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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...

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.