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

2's complement conversion. Is this right?

I'm reading 3-byte numbers from a file and they are signed (+8 to
-8million). This seems to work, but I'm not sure it's right.

# Convert the 3-characters into a number.
Value1, Value2, Value3 = unpack(">BBB", Buffer[s:s+3])
Value = (Value1*65536)+(Value2*256)+Value3
if Value >= 0x800000:
Value -= 0x1000000
print Value

For example:
16682720 = -94496

Should it be Value -= 0x1000001 so that I get -94497, instead?

Thanks!

Bob

Jun 27 '08 #1
32 5875
On 2008-04-18, Bob Greschke <bo*@passcal.nmt.eduwrote:
I'm reading 3-byte numbers from a file and they are signed (+8 to
-8million). This seems to work, but I'm not sure it's right.

# Convert the 3-characters into a number.
Value1, Value2, Value3 = unpack(">BBB", Buffer[s:s+3])
Value = (Value1*65536)+(Value2*256)+Value3
if Value >= 0x800000:
Value -= 0x1000000
print Value

For example:
16682720 = -94496

Should it be Value -= 0x1000001 so that I get -94497, instead?
Nope. -94496 is the right answer:
>>-94496 & 0xffffff
16682720

Here's another way to do it:

------------------------------------------------------------------
import struct

def tohex(s):
return '0x' + ''.join(['%0.2x' % ord(b) for b in s])

def from3Bytes(s):
# sign extend the three byte number in s to make it 4 bytes long
if ord(s[0]) & 0x80:
s = '\xff'+s
else:
s = '\x00'+s
return struct.unpack('>i',s)[0]

for v in 0,1,-2,500,-500,7777,-7777,-94496,98765,-98765,8388607,-8388607,-8388608:
s = struct.pack('>i',v)[1:]
print "%8d %s %8d" % (v, tohex(s), from3Bytes(s))
------------------------------------------------------------------
--
Grant Edwards grante Yow! I'll eat ANYTHING
at that's BRIGHT BLUE!!
visi.com
Jun 27 '08 #2
Bob Greschke <bo*@passcal.nmt.eduwrote:
>I'm reading 3-byte numbers from a file and they are signed (+8 to
-8million). This seems to work, but I'm not sure it's right.

# Convert the 3-characters into a number.
Value1, Value2, Value3 = unpack(">BBB", Buffer[s:s+3])
Value = (Value1*65536)+(Value2*256)+Value3
if Value >= 0x800000:
Value -= 0x1000000
print Value

For example:
16682720 = -94496

Should it be Value -= 0x1000001 so that I get -94497, instead?
Your first case is correct, "Value -= 0x1000000". The value 0xFFFFFFF
should be -1 and 0xFFFFFFF - 0x1000000 == -1.

An alternative way of doing this:

Value = unpack(">l", Buffer[s:s+3] + "\0")[0] >8

Ross Ridge

--
l/ // Ross Ridge -- The Great HTMU
[oo][oo] rr****@csclub.uwaterloo.ca
-()-/()/ http://www.csclub.uwaterloo.ca/~rridge/
db //
Jun 27 '08 #3
On 2008-04-18 14:37:21 -0600, Ross Ridge
<rr****@caffeine.csclub.uwaterloo.casaid:
Bob Greschke <bo*@passcal.nmt.eduwrote:
>I'm reading 3-byte numbers from a file and they are signed (+8 to
-8million). This seems to work, but I'm not sure it's right.

# Convert the 3-characters into a number.
Value1, Value2, Value3 = unpack(">BBB", Buffer[s:s+3])
Value = (Value1*65536)+(Value2*256)+Value3
if Value >= 0x800000:
Value -= 0x1000000
print Value

For example:
16682720 = -94496

Should it be Value -= 0x1000001 so that I get -94497, instead?

Your first case is correct, "Value -= 0x1000000". The value 0xFFFFFFF
should be -1 and 0xFFFFFFF - 0x1000000 == -1.

An alternative way of doing this:

Value = unpack(">l", Buffer[s:s+3] + "\0")[0] >8

Ross Ridge
Good to know (never was good on the math front).

However, in playing around with your suggestion and Grant's code I've
found that the struct stuff is WAY slower than doing something like this

Value = (ord(Buf[s])*65536)+(ord(Buf[s+1])*256)+ord(Buf[s+2])
if Value >= 0x800000:
Value -= 0x1000000

This is almost twice as fast just sitting here grinding through a few
hundred thousand conversions (like 3sec vs. ~5secs just counting on my
fingers - on an old Sun...it's a bit slow). Replacing *65536 with <<16
and *256 with <<8 might even be a little faster, but it's too close to
call without really profiling it.

I wasn't planning on making this discovery today! :)

Bob

Jun 27 '08 #4
On Apr 18, 5:26*pm, Bob Greschke <b...@passcal.nmt.eduwrote:
On 2008-04-18 14:37:21 -0600, Ross Ridge
<rri...@caffeine.csclub.uwaterloo.casaid:
Bob Greschke *<b...@passcal.nmt.eduwrote:
I'm reading 3-byte numbers from a file and they are signed (+8 to
-8million). *This seems to work, but I'm not sure it's right.
# Convert the 3-characters into a number.
Value1, Value2, Value3 = unpack(">BBB", Buffer[s:s+3])
Value = (Value1*65536)+(Value2*256)+Value3
if Value >= 0x800000:
Value -= 0x1000000
print Value
For example:
16682720 = -94496
Should it be Value -= 0x1000001 so that I get -94497, instead?
Your first case is correct, "Value -= 0x1000000". *The value 0xFFFFFFF
should be -1 and 0xFFFFFFF - 0x1000000 == -1.
An alternative way of doing this:
* *Value = unpack(">l", Buffer[s:s+3] + "\0")[0] >8
* * * * * * * * * * * * * * * * * *Ross Ridge

Good to know (never was good on the math front).

However, in playing around with your suggestion and Grant's code I've
found that the struct stuff is WAY slower than doing something like this

*Value = (ord(Buf[s])*65536)+(ord(Buf[s+1])*256)+ord(Buf[s+2])
*if Value >= 0x800000:
* * *Value -= 0x1000000

This is almost twice as fast just sitting here grinding through a few
hundred thousand conversions (like 3sec vs. ~5secs just counting on my
fingers - on an old Sun...it's a bit slow). *
You'd better use a more precise timing method than finger counting,
such as timeit. Twice as fast is probably a gross overestimation; on
my box (Python 2.5, WinXP) avoiding unpack is around 10% and 40%
faster from Ross's and Grant's method, respectively:

python -m timeit "for i in xrange(1000):from3Bytes_bob(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 1.02 msec per loop

python -m timeit "for i in xrange(1000):from3Bytes_grant(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 1.43 msec per loop

python -m timeit "for i in xrange(1000):from3Bytes_ross(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 1.12 msec per loop

### bin.py ##########################################

from struct import unpack

def from3Bytes_bob(s):
Value = (ord(s[0])<<16) + (ord(s[1])<<8) + ord(s[2])
if Value >= 0x800000:
Value -= 0x1000000
return Value

def from3Bytes_grant(s):
if ord(s[0]) & 0x80:
s = '\xff'+s
else:
s = '\x00'+s
return unpack('>i',s)[0]

def from3Bytes_ross(s):
return unpack(">l", s + "\0")[0] >8

Replacing *65536 with <<16
and *256 with <<8 might even be a little faster, but it's too close to
call without really profiling it.
I wasn't planning on making this discovery today! :)

Bob
If you are running this on a 32-bit architecture, get Psyco [1] and
add at the top of your module:
import psyco; psyco.full()

Using Psyco in this scenatio is up to 70% faster:

python -m timeit "for i in xrange(1000):from3Bytes_bob(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 624 usec per loop

python -m timeit "for i in xrange(1000):from3Bytes_grant(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 838 usec per loop

python -m timeit "for i in xrange(1000):from3Bytes_ross(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 834 usec per loop
George

[1] http://psyco.sourceforge.net/
Jun 27 '08 #5
On 2008-04-18 16:04:37 -0600, George Sakkis <ge***********@gmail.comsaid:
On Apr 18, 5:26*pm, Bob Greschke <b...@passcal.nmt.eduwrote:
>On 2008-04-18 14:37:21 -0600, Ross Ridge
<rri...@caffeine.csclub.uwaterloo.casaid:
>>Bob Greschke *<b...@passcal.nmt.eduwrote:
I'm reading 3-byte numbers from a file and they are signed (+8 to
-8million). *This seems to work, but I'm not sure it's right.
>>># Convert the 3-characters into a number.
Value1, Value2, Value3 = unpack(">BBB", Buffer[s:s+3])
Value = (Value1*65536)+(Value2*256)+Value3
if Value >= 0x800000:
Value -= 0x1000000
print Value
>>>For example:
16682720 = -94496
>>>Should it be Value -= 0x1000001 so that I get -94497, instead?
>>Your first case is correct, "Value -= 0x1000000". *The value 0xFFFFF
FF
>>should be -1 and 0xFFFFFFF - 0x1000000 == -1.
>>An alternative way of doing this:
>>* *Value = unpack(">l", Buffer[s:s+3] + "\0")[0] >8
>>* * * * * * * * * * * * * * * * * *R
oss Ridge
>>
Good to know (never was good on the math front).

However, in playing around with your suggestion and Grant's code I've
found that the struct stuff is WAY slower than doing something like this

*Value = (ord(Buf[s])*65536)+(ord(Buf[s+1])*256)+ord(Buf[s+2])
*if Value >= 0x800000:
* * *Value -= 0x1000000

This is almost twice as fast just sitting here grinding through a few
hundred thousand conversions (like 3sec vs. ~5secs just counting on my
fingers - on an old Sun...it's a bit slow). *

You'd better use a more precise timing method than finger counting,
such as timeit. Twice as fast is probably a gross overestimation; on
my box (Python 2.5, WinXP) avoiding unpack is around 10% and 40%
faster from Ross's and Grant's method, respectively:

python -m timeit "for i in xrange(1000):from3Bytes_bob(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 1.02 msec per loop

python -m timeit "for i in xrange(1000):from3Bytes_grant(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 1.43 msec per loop

python -m timeit "for i in xrange(1000):from3Bytes_ross(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 1.12 msec per loop

### bin.py ##########################################

from struct import unpack

def from3Bytes_bob(s):
Value = (ord(s[0])<<16) + (ord(s[1])<<8) + ord(s[2])
if Value >= 0x800000:
Value -= 0x1000000
return Value

def from3Bytes_grant(s):
if ord(s[0]) & 0x80:
s = '\xff'+s
else:
s = '\x00'+s
return unpack('>i',s)[0]

def from3Bytes_ross(s):
return unpack(">l", s + "\0")[0] >8

>Replacing *65536 with <<16
and *256 with <<8 might even be a little faster, but it's too close to
call without really profiling it.
>I wasn't planning on making this discovery today! :)

Bob

If you are running this on a 32-bit architecture, get Psyco [1] and
add at the top of your module:
import psyco; psyco.full()

Using Psyco in this scenatio is up to 70% faster:

python -m timeit "for i in xrange(1000):from3Bytes_bob(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 624 usec per loop

python -m timeit "for i in xrange(1000):from3Bytes_grant(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 838 usec per loop

python -m timeit "for i in xrange(1000):from3Bytes_ross(s)" \
-s "from bin import *; s=pack('>i',1234567)[1:]"
1000 loops, best of 3: 834 usec per loop
George

[1] http://psyco.sourceforge.net/
I'm on a Solaris 8 with Python 2.3.4 and when crunching through,
literally, millions and millions of samples of seismic data fingers
point out the difference nicely. :) I'll look into this more on some
of our bigger better faster machines (there is no -m option for timeit
on the Sun :). The Sun is just what I develop on. If stuff runs fast
enough to keep me awake on there over an ssh'ed X11 connection it
should run even better on the real field equipment (Macs, Linuxes,
WinXPs).

Never heard of Psyco. That's nice!

Thanks!

Bob

Jun 27 '08 #6
George Sakkis <ge***********@gmail.comwrote:
>You'd better use a more precise timing method than finger counting,
such as timeit. Twice as fast is probably a gross overestimation; on
my box (Python 2.5, WinXP) avoiding unpack is around 10% and 40%
faster from Ross's and Grant's method, respectively:
....
>def from3Bytes_ross(s):
return unpack(">l", s + "\0")[0] >8
If you have Python 2.5, here's a faster version:

from struct import *
unpack_i32be = Struct(">l").unpack

def from3Bytes_ross2(s):
return unpack_i32be(s + "\0")[0] >8

Ross Ridge

--
l/ // Ross Ridge -- The Great HTMU
[oo][oo] rr****@csclub.uwaterloo.ca
-()-/()/ http://www.csclub.uwaterloo.ca/~rridge/
db //
Jun 27 '08 #7
On 2008-04-18 17:55:32 -0600, Ross Ridge
<rr****@caffeine.csclub.uwaterloo.casaid:
George Sakkis <ge***********@gmail.comwrote:
>You'd better use a more precise timing method than finger counting,
such as timeit. Twice as fast is probably a gross overestimation; on
my box (Python 2.5, WinXP) avoiding unpack is around 10% and 40%
faster from Ross's and Grant's method, respectively:
...
>def from3Bytes_ross(s):
return unpack(">l", s + "\0")[0] >8

If you have Python 2.5, here's a faster version:

from struct import *
unpack_i32be = Struct(">l").unpack

def from3Bytes_ross2(s):
return unpack_i32be(s + "\0")[0] >8

Ross Ridge
That's not even intelligible. I wanna go back to COBOL. :)

Jun 27 '08 #8
Ross Ridge <rr****@caffeine.csclub.uwaterloo.casaid:
If you have Python 2.5, here's a faster version:

from struct import *
unpack_i32be = Struct(">l").unpack

def from3Bytes_ross2(s):
return unpack_i32be(s + "\0")[0] >8

Bob Greschke <bo*@passcal.nmt.eduwrote:
That's not even intelligible. I wanna go back to COBOL. :)
It's the same as the previous version except that it "precompiles"
the struct.unpack() format string. It works similar to the way Python
handles regular expressions.

Ross Ridge

--
l/ // Ross Ridge -- The Great HTMU
[oo][oo] rr****@csclub.uwaterloo.ca
-()-/()/ http://www.csclub.uwaterloo.ca/~rridge/
db //
Jun 27 '08 #9
On 2008-04-18, Bob Greschke <bo*@passcal.nmt.eduwrote:
However, in playing around with your suggestion and Grant's code I've
found that the struct stuff is WAY slower than doing something like this

Value = (ord(Buf[s])*65536)+(ord(Buf[s+1])*256)+ord(Buf[s+2])
if Value >= 0x800000:
Value -= 0x1000000

This is almost twice as fast just sitting here grinding through a few
hundred thousand conversions (like 3sec vs. ~5secs just counting on my
fingers - on an old Sun...it's a bit slow). Replacing *65536 with <<16
and *256 with <<8 might even be a little faster, but it's too close to
call without really profiling it.
I didn't know speed was important. This might be a little
faster (depending on hardware):

Value = (ord(Buf[s])<<16) | (ord(Buf[s+1])<<8) | ord(Buf[s+2])

It also makes the intention a bit more obvious (at least to me).

A decent C compiler will recognize that <<16 and <<8 are
special and just move bytes around rather than actually doing
shifts. I doubt the Python compiler does optimizations like
that, but shifts are still usually faster than multiplies
(though, again, a good compiler will recognize that multiplying
by 65536 is the same as shifting by 16 and just move bytes
around).

--
Grant Edwards grante Yow! If elected, Zippy
at pledges to each and every
visi.com American a 55-year-old
houseboy...
Jun 27 '08 #10
On 2008-04-18, Bob Greschke <bo*@passcal.nmt.eduwrote:
I'm on a Solaris 8 with Python 2.3.4 and when crunching
through, literally, millions and millions of samples of
seismic data fingers point out the difference nicely. :) I'll
look into this more on some of our bigger better faster
machines (there is no -m option for timeit on the Sun :). The
Sun is just what I develop on. If stuff runs fast enough to
keep me awake on there over an ssh'ed X11 connection it
should run even better on the real field equipment (Macs,
Linuxes, WinXPs).
If time is an issue, I might write a C program to convert the
files from 24-bit numbers to 32-bit numbers. Then you can use
numpy to load huge arrays of them in a single whack.

--
Grant Edwards grante Yow! .. he dominates the
at DECADENT SUBWAY SCENE.
visi.com
Jun 27 '08 #11
On Fri, 18 Apr 2008 22:30:45 -0500, Grant Edwards wrote:
On 2008-04-18, Bob Greschke <bo*@passcal.nmt.eduwrote:
>However, in playing around with your suggestion and Grant's code I've
found that the struct stuff is WAY slower than doing something like
this

Value = (ord(Buf[s])*65536)+(ord(Buf[s+1])*256)+ord(Buf[s+2]) if Value
> >= 0x800000:
Value -= 0x1000000

This is almost twice as fast just sitting here grinding through a few
hundred thousand conversions (like 3sec vs. ~5secs just counting on my
fingers - on an old Sun...it's a bit slow). Replacing *65536 with <<16
and *256 with <<8 might even be a little faster, but it's too close to
call without really profiling it.

I didn't know speed was important. This might be a little faster
(depending on hardware):

Value = (ord(Buf[s])<<16) | (ord(Buf[s+1])<<8) | ord(Buf[s+2])

It also makes the intention a bit more obvious (at least to me).

A decent C compiler will recognize that <<16 and <<8 are special and
just move bytes around rather than actually doing shifts. I doubt the
Python compiler does optimizations like that, but shifts are still
usually faster than multiplies (though, again, a good compiler will
recognize that multiplying by 65536 is the same as shifting by 16 and
just move bytes around).
So why not put it in C extension?

It's easier than most people think:

<code>
from3bytes.c
============
#include <Python.h>

PyObject*
from3bytes(PyObject* self, PyObject* args)
{
const char * s;
int len;
if (!PyArg_ParseTuple(args, "s#", &s, &len))
return NULL;
long n = (s[0]<<16) | (s[1]<<8) | s[2];
if (n >= 0x800000)
n -= 0x1000000;
return PyInt_FromLong(n);
}

static PyMethodDef functions[] = {
{"from3bytes", (PyCFunction)from3bytes, METH_VARARGS},
{NULL, NULL, 0, NULL},
};
DL_EXPORT(void)
init_from3bytes(void)
{
Py_InitModule("_from3bytes", functions);
}

buildme.py
==========
import os
import sys
from distutils.core import Extension, setup

os.chdir(os.path.dirname(os.path.abspath(__file__) ))
sys.argv = [sys.argv[0], 'build_ext', '-i']
setup(ext_modules = [Extension('_from3bytes', ['from3bytes.c'])])
</code>

'python buildme.py' will create '_from3bytes.so' file
'from _from3bytes import from3bytes' will import C-optimized function

Hope this helps.

--
Ivan Illarionov
Jun 27 '08 #12
On Sat, 19 Apr 2008 04:45:54 +0000, Ivan Illarionov wrote:
On Fri, 18 Apr 2008 22:30:45 -0500, Grant Edwards wrote:
>On 2008-04-18, Bob Greschke <bo*@passcal.nmt.eduwrote:
>>However, in playing around with your suggestion and Grant's code I've
found that the struct stuff is WAY slower than doing something like
this

Value = (ord(Buf[s])*65536)+(ord(Buf[s+1])*256)+ord(Buf[s+2]) if
Value
>= 0x800000:
Value -= 0x1000000

This is almost twice as fast just sitting here grinding through a few
hundred thousand conversions (like 3sec vs. ~5secs just counting on my
fingers - on an old Sun...it's a bit slow). Replacing *65536 with
<<16 and *256 with <<8 might even be a little faster, but it's too
close to call without really profiling it.

I didn't know speed was important. This might be a little faster
(depending on hardware):

Value = (ord(Buf[s])<<16) | (ord(Buf[s+1])<<8) | ord(Buf[s+2])

It also makes the intention a bit more obvious (at least to me).

A decent C compiler will recognize that <<16 and <<8 are special and
just move bytes around rather than actually doing shifts. I doubt the
Python compiler does optimizations like that, but shifts are still
usually faster than multiplies (though, again, a good compiler will
recognize that multiplying by 65536 is the same as shifting by 16 and
just move bytes around).

So why not put it in C extension?

It's easier than most people think:

<code>
from3bytes.c
============
#include <Python.h>

PyObject*
from3bytes(PyObject* self, PyObject* args) {
const char * s;
int len;
if (!PyArg_ParseTuple(args, "s#", &s, &len))
return NULL;
long n = (s[0]<<16) | (s[1]<<8) | s[2]; if (n >= 0x800000)
n -= 0x1000000;
return PyInt_FromLong(n);
}

static PyMethodDef functions[] = {
{"from3bytes", (PyCFunction)from3bytes, METH_VARARGS}, {NULL,
NULL, 0, NULL},
};
DL_EXPORT(void)
init_from3bytes(void)
{
Py_InitModule("_from3bytes", functions);
}

buildme.py
==========
import os
import sys
from distutils.core import Extension, setup

os.chdir(os.path.dirname(os.path.abspath(__file__) )) sys.argv =
[sys.argv[0], 'build_ext', '-i'] setup(ext_modules =
[Extension('_from3bytes', ['from3bytes.c'])]) </code>

'python buildme.py' will create '_from3bytes.so' file 'from _from3bytes
import from3bytes' will import C-optimized function

Hope this helps.
Sorry,
the right code should be:

PyObject*
from3bytes(PyObject* self, PyObject* args)
{
const char * s;
int len;
if (!PyArg_ParseTuple(args, "s#", &s, &len))
return NULL;

long n = ((((unsigned char)s[0])<<16) | (((unsigned char)s[1])<<8) |
((unsigned char)s[2]));
if (n >= 0x800000)
n -= 0x1000000;
return PyInt_FromLong(n);
}
Jun 27 '08 #13
On 2008-04-18 23:35:12 -0600, Ivan Illarionov <iv*************@gmail.comsaid:
On Sat, 19 Apr 2008 04:45:54 +0000, Ivan Illarionov wrote:
>On Fri, 18 Apr 2008 22:30:45 -0500, Grant Edwards wrote:
>>On 2008-04-18, Bob Greschke <bo*@passcal.nmt.eduwrote:

However, in playing around with your suggestion and Grant's code I've
found that the struct stuff is WAY slower than doing something like
this

Value = (ord(Buf[s])*65536)+(ord(Buf[s+1])*256)+ord(Buf[s+2]) if
Value
= 0x800000:
Value -= 0x1000000

This is almost twice as fast just sitting here grinding through a few
hundred thousand conversions (like 3sec vs. ~5secs just counting on my
fingers - on an old Sun...it's a bit slow). Replacing *65536 with
<<16 and *256 with <<8 might even be a little faster, but it's too
close to call without really profiling it.

I didn't know speed was important. This might be a little faster
(depending on hardware):

Value = (ord(Buf[s])<<16) | (ord(Buf[s+1])<<8) | ord(Buf[s+2])

It also makes the intention a bit more obvious (at least to me).

A decent C compiler will recognize that <<16 and <<8 are special and
just move bytes around rather than actually doing shifts. I doubt the
Python compiler does optimizations like that, but shifts are still
usually faster than multiplies (though, again, a good compiler will
recognize that multiplying by 65536 is the same as shifting by 16 and
just move bytes around).

So why not put it in C extension?

It's easier than most people think:

<code>
from3bytes.c
============
#include <Python.h>

PyObject*
from3bytes(PyObject* self, PyObject* args) {
const char * s;
int len;
if (!PyArg_ParseTuple(args, "s#", &s, &len))
return NULL;
long n = (s[0]<<16) | (s[1]<<8) | s[2]; if (n >= 0x800000)
n -= 0x1000000;
return PyInt_FromLong(n);
}

static PyMethodDef functions[] = {
{"from3bytes", (PyCFunction)from3bytes, METH_VARARGS}, {NULL,
NULL, 0, NULL},
};
DL_EXPORT(void)
init_from3bytes(void)
{
Py_InitModule("_from3bytes", functions);
}

buildme.py
==========
import os
import sys
from distutils.core import Extension, setup

os.chdir(os.path.dirname(os.path.abspath(__file__ ))) sys.argv =
[sys.argv[0], 'build_ext', '-i'] setup(ext_modules =
[Extension('_from3bytes', ['from3bytes.c'])]) </code>

'python buildme.py' will create '_from3bytes.so' file 'from _from3bytes
import from3bytes' will import C-optimized function

Hope this helps.

Sorry,
the right code should be:

PyObject* from3bytes(PyObject* self, PyObject* args)
{
const char * s;
int len;
if (!PyArg_ParseTuple(args, "s#", &s, &len))
return NULL;
long n = ((((unsigned char)s[0])<<16) | (((unsigned char)s[1])<<8) |
((unsigned char)s[2]));
if (n >= 0x800000)
n -= 0x1000000;
return PyInt_FromLong(n);
}
No thanks. Being able to alter and install these programs on whatever
computer they are installed on is more important than speed. I went
down the C-extension path years ago and it turned into a big mess.
Everything has to run on Sun's, Mac's, Linux and Windows without any
major hassels if they have to be changed. I can't reley on everything
the program needs to be rebuilt being installed beyond Python and
Tkinter (and pySerial and PIL for a couple of programs), which they
need to run. So no compiling and everything is in one file, in case a
new version has to be upgraded by a user by emailing it to them while
they're sitting on some mountain in Tibet. Just unzip, stick the .py
somewhere logical, (usually) double-click, and they are off and running.

Bob
Jun 27 '08 #14
On 2008-04-18 21:33:34 -0600, Grant Edwards <gr****@visi.comsaid:
On 2008-04-18, Bob Greschke <bo*@passcal.nmt.eduwrote:
>I'm on a Solaris 8 with Python 2.3.4 and when crunching
through, literally, millions and millions of samples of
seismic data fingers point out the difference nicely. :) I'll
look into this more on some of our bigger better faster
machines (there is no -m option for timeit on the Sun :). The
Sun is just what I develop on. If stuff runs fast enough to
keep me awake on there over an ssh'ed X11 connection it should run even
better on the real field equipment (Macs,
Linuxes, WinXPs).

If time is an issue, I might write a C program to convert the
files from 24-bit numbers to 32-bit numbers. Then you can use
numpy to load huge arrays of them in a single whack.
Yes you could. :) But this is all in real time (as in 'gotta have it
right now' real time). Plus we're dealing with 100's of files
(instruments) at a time. It'll be 1000's of instruments this summer up
in Canada.

Here's the program having happily crunched away at nearly twice the
speed it was the day before yesterday.

www.greschke.com/unlinked/files/pocus.png

The white dots come from the 3-byte integers and make up the green line
which makes up one 'logical' chunk (in this case they recorded for
60mins at a time) of a whole data file with one file per instrument.
Generally we just take a quick look at the green lines to make sure the
instruments were working, and pull out the bad ones so they don't get
used again until they've been looked at. Zooming in to the level where
you can see the individual samples is used to (more) accurately
determine the time when an [intentional] explosion was set off. You
use instruments placed near the shot holes for that. Simple. :)

Bob

Jun 27 '08 #15
On Apr 18, 9:36*pm, Ross Ridge <rri...@caffeine.csclub.uwaterloo.ca>
wrote:
Ross Ridge <rri...@caffeine.csclub.uwaterloo.casaid:
If you have Python 2.5, here's a faster version:
* *from struct import *
* *unpack_i32be = Struct(">l").unpack
* *def from3Bytes_ross2(s):
* * * *return unpack_i32be(s + "\0")[0] >8

Bob Greschke *<b...@passcal.nmt.eduwrote:
That's not even intelligible. *I wanna go back to COBOL. :)

It's the same as the previous version except that it "precompiles"
the struct.unpack() format string. *It works similar to the way Python
handles regular expressions.
I didn't know about the Struct class; pretty neat. It's amazing that
this version without Psyco is as fast Bob's version with Psyco! Adding
Psyco to it though makes it *slower*, not faster. So here's how I'd
write it (if I wanted or had to stay in pure Python):

try: import psyco
except ImportError:
from struct import Struct
unpack_i32be = Struct(">l").unpack
def from3Bytes(s):
return unpack_i32be(s + "\0")[0] >8
else:
def from3Bytes(s):
Value = (ord(s[0])<<16) + (ord(s[1])<<8) + ord(s[2])
if Value >= 0x800000:
Value -= 0x1000000
return Value
psyco.bind(from3Bytes)
HTH,
George
Jun 27 '08 #17
Ross Ridge <rri...@caffeine.csclub.uwaterloo.cawrote:
It's the same as the previous version except that it "precompiles"
the struct.unpack() format string. =A0It works similar to the way Python
handles regular expressions.
George Sakkis <ge***********@gmail.comwrote:
>I didn't know about the Struct class; pretty neat. It's amazing that
this version without Psyco is as fast Bob's version with Psyco!
Unfortunately, it doesn't seem to documented in the Python 2.5 manual.
The speed improvement mainly comes from avoiding the Python code in the
struct module that wraps the Struct class. The struct module caches
already compiled format strings, but looking format strings in the cache
ends taking a fair chunk of time in my original example.

Ross Ridge

--
l/ // Ross Ridge -- The Great HTMU
[oo][oo] rr****@csclub.uwaterloo.ca
-()-/()/ http://www.csclub.uwaterloo.ca/~rridge/
db //
Jun 27 '08 #18
Ross Ridge wrote:
Ross Ridge <rri...@caffeine.csclub.uwaterloo.cawrote:
>It's the same as the previous version except that it "precompiles"
the struct.unpack() format string. =A0It works similar to the way Python
handles regular expressions.

George Sakkis <ge***********@gmail.comwrote:
>I didn't know about the Struct class; pretty neat. It's amazing that
this version without Psyco is as fast Bob's version with Psyco!

Unfortunately, it doesn't seem to documented in the Python 2.5 manual.
It seems to me that it's documented:

http://docs.python.org/lib/struct-objects.html

The struct module doc page
(http://docs.python.org/lib/module-struct.html) provides links but no
explicit mention of the Struct class in its text.

Jun 27 '08 #19
Bob Greschke wrote:
On 2008-04-18 23:35:12 -0600, Ivan Illarionov <iv*************@gmail.com>
said:
>On Sat, 19 Apr 2008 04:45:54 +0000, Ivan Illarionov wrote:
>>On Fri, 18 Apr 2008 22:30:45 -0500, Grant Edwards wrote:

On 2008-04-18, Bob Greschke <bo*@passcal.nmt.eduwrote:

However, in playing around with your suggestion and Grant's code I've
found that the struct stuff is WAY slower than doing something like
this
>
Value = (ord(Buf[s])*65536)+(ord(Buf[s+1])*256)+ord(Buf[s+2]) if
Value
>= 0x800000:
Value -= 0x1000000
>
This is almost twice as fast just sitting here grinding through a few
hundred thousand conversions (like 3sec vs. ~5secs just counting on my
fingers - on an old Sun...it's a bit slow). Replacing *65536 with
<<16 and *256 with <<8 might even be a little faster, but it's too
close to call without really profiling it.

I didn't know speed was important. This might be a little faster
(depending on hardware):

Value = (ord(Buf[s])<<16) | (ord(Buf[s+1])<<8) | ord(Buf[s+2])

It also makes the intention a bit more obvious (at least to me).

A decent C compiler will recognize that <<16 and <<8 are special and
just move bytes around rather than actually doing shifts. I doubt the
Python compiler does optimizations like that, but shifts are still
usually faster than multiplies (though, again, a good compiler will
recognize that multiplying by 65536 is the same as shifting by 16 and
just move bytes around).

So why not put it in C extension?

It's easier than most people think:

<code>
from3bytes.c
============
#include <Python.h>

PyObject*
from3bytes(PyObject* self, PyObject* args) {
const char * s;
int len;
if (!PyArg_ParseTuple(args, "s#", &s, &len))
return NULL;
long n = (s[0]<<16) | (s[1]<<8) | s[2]; if (n >= 0x800000)
n -= 0x1000000;
return PyInt_FromLong(n);
}

static PyMethodDef functions[] = {
{"from3bytes", (PyCFunction)from3bytes, METH_VARARGS}, {NULL,
NULL, 0, NULL},
};
DL_EXPORT(void)
init_from3bytes(void)
{
Py_InitModule("_from3bytes", functions);
}

buildme.py
==========
import os
import sys
from distutils.core import Extension, setup

os.chdir(os.path.dirname(os.path.abspath(__file_ _))) sys.argv =
[sys.argv[0], 'build_ext', '-i'] setup(ext_modules =
[Extension('_from3bytes', ['from3bytes.c'])]) </code>

'python buildme.py' will create '_from3bytes.so' file 'from _from3bytes
import from3bytes' will import C-optimized function

Hope this helps.

Sorry,
the right code should be:

PyObject* from3bytes(PyObject* self, PyObject* args)
{
const char * s;
int len;
if (!PyArg_ParseTuple(args, "s#", &s, &len))
return NULL;
long n = ((((unsigned char)s[0])<<16) | (((unsigned
char)s[1])<<8) |
((unsigned char)s[2]));
if (n >= 0x800000)
n -= 0x1000000;
return PyInt_FromLong(n);
}

No thanks. Being able to alter and install these programs on whatever
computer they are installed on is more important than speed. I went
down the C-extension path years ago and it turned into a big mess.
Everything has to run on Sun's, Mac's, Linux and Windows without any
major hassels if they have to be changed. I can't reley on everything
the program needs to be rebuilt being installed beyond Python and
Tkinter (and pySerial and PIL for a couple of programs), which they
need to run. So no compiling and everything is in one file, in case a
new version has to be upgraded by a user by emailing it to them while
they're sitting on some mountain in Tibet. Just unzip, stick the .py
somewhere logical, (usually) double-click, and they are off and running.

Bob
Just for fun, here's a way to convert lots of 3-byte integers using PIL:

from PIL import Image
import array

def int3_pil(s, trafo="\x00"*128+"\xff"*128):
n = len(s)//3
im = Image.new("RGB", (n, 1))
im.fromstring(s)
hi, mid, lo = im.split()
sign = Image.new("L", (n, 1))
sign.fromstring(hi.tostring().translate(trafo))
im = Image.merge("RGBA", (lo, mid, hi, sign))
a = array.array("i")
a.fromstring(im.tostring())
return a.tolist()

Not as fast as I had hoped, though. Also, it needs some work to make it
independent of the processor architecture.

Peter
Jun 27 '08 #20
On 20 , 04:10, George Sakkis <george.sak...@gmail.comwrote:
On Apr 18, 9:36 pm, Ross Ridge <rri...@caffeine.csclub.uwaterloo.ca>
wrote:
Ross Ridge <rri...@caffeine.csclub.uwaterloo.casaid:
If you have Python 2.5, here's a faster version:
from struct import *
unpack_i32be = Struct(">l").unpack
def from3Bytes_ross2(s):
return unpack_i32be(s + "\0")[0] >8
Bob Greschke <b...@passcal.nmt.eduwrote:
That's not even intelligible. I wanna go back to COBOL. :)
It's the same as the previous version except that it "precompiles"
the struct.unpack() format string. It works similar to the way Python
handles regular expressions.

I didn't know about the Struct class; pretty neat. It's amazing that
this version without Psyco is as fast Bob's version with Psyco! Adding
Psyco to it though makes it *slower*, not faster. So here's how I'd
write it (if I wanted or had to stay in pure Python):

try: import psyco
except ImportError:
from struct import Struct
unpack_i32be = Struct(">l").unpack
def from3Bytes(s):
return unpack_i32be(s + "\0")[0] >8
else:
def from3Bytes(s):
Value = (ord(s[0])<<16) + (ord(s[1])<<8) + ord(s[2])
if Value >= 0x800000:
Value -= 0x1000000
return Value
psyco.bind(from3Bytes)

HTH,
George
I was able to get even faster pure-python version using array module:

a = array.array('l', ''.join(('\0' + s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()

It actually moves bytes around on C level.
test code:
import struct
import array
import sys

unpack_i32be = struct.Struct(">l").unpack
s = ''.join(struct.pack('>i', 1234567)[1:]*1000)

def from3bytes_ord(s):
values = []
for i in xrange(0, len(s), 3):
Value = (ord(s[i])<<16) | (ord(s[i+1])<<8) | ord(s[i+2])
if Value >= 0x800000:
Value -= 0x1000000
values.append(Value)
return values

def from3bytes_struct(s):
return [unpack_i32be(s[i:i+3] + "\0")[0] >8 for i in xrange(0,
len(s), 3)]

def from3bytes_array(s):
a = array.array('l', ''.join(('\0' + s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
return a.tolist()

from timeit import Timer

t1 = Timer("from3bytes_ord(s)", "from __main__ import s,
from3bytes_ord")
t2 = Timer("from3bytes_struct(s)", "from __main__ import s,
from3bytes_struct")
t3 = Timer("from3bytes_array(s)", "from __main__ import s,
from3bytes_array")

print 'ord:\t', t1.timeit(1000)
print 'struct:\t', t2.timeit(1000)
print 'array:\t', t3.timeit(1000)

Output:
ord: 7.08213110884
struct: 3.7689164405
array: 2.62995268952

Inspired by Guido's essay http://www.python.org/doc/essays/list2str/
Jun 27 '08 #21
On 22 апр, 00:10, Ivan Illarionov <ivan.illario...@gmail.com>wrote:
On 20 ÁÐÒ, 04:10, George Sakkis <george.sak...@gmail.comwrote:
On Apr 18, 9:36 pm, Ross Ridge <rri...@caffeine.csclub.uwaterloo.ca>
wrote:
Ross Ridge <rri...@caffeine.csclub.uwaterloo.casaid:
If you have Python 2.5, here's a faster version:
from struct import *
unpack_i32be = Struct(">l").unpack
def from3Bytes_ross2(s):
return unpack_i32be(s + "\0")[0] >8
Bob Greschke <b...@passcal.nmt.eduwrote:
That's not even intelligible. I wanna go back to COBOL. :)
It's the same as the previous version except that it "precompiles"
the struct.unpack() format string. It works similar to the way Python
handles regular expressions.
I didn't know about the Struct class; pretty neat. It's amazing that
this version without Psyco is as fast Bob's version with Psyco! Adding
Psyco to it though makes it *slower*, not faster. So here's how I'd
write it (if I wanted or had to stay in pure Python):
try: import psyco
except ImportError:
from struct import Struct
unpack_i32be = Struct(">l").unpack
def from3Bytes(s):
return unpack_i32be(s + "\0")[0] >8
else:
def from3Bytes(s):
Value = (ord(s[0])<<16) + (ord(s[1])<<8) + ord(s[2])
if Value >= 0x800000:
Value -= 0x1000000
return Value
psyco.bind(from3Bytes)
HTH,
George

I was able to get even faster pure-python version using array module:

a = array.array('l', ''.join(('\0' + s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()

It actually moves bytes around on C level.

test code:
import struct
import array
import sys

unpack_i32be = struct.Struct(">l").unpack
s = ''.join(struct.pack('>i', 1234567)[1:]*1000)

def from3bytes_ord(s):
values = []
for i in xrange(0, len(s), 3):
Value = (ord(s[i])<<16) | (ord(s[i+1])<<8) | ord(s[i+2])
if Value >= 0x800000:
Value -= 0x1000000
values.append(Value)
return values

def from3bytes_struct(s):
return [unpack_i32be(s[i:i+3] + "\0")[0] >8 for i in xrange(0,
len(s), 3)]

def from3bytes_array(s):
a = array.array('l', ''.join(('\0' + s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
return a.tolist()

from timeit import Timer

t1 = Timer("from3bytes_ord(s)", "from __main__ import s,
from3bytes_ord")
t2 = Timer("from3bytes_struct(s)", "from __main__ import s,
from3bytes_struct")
t3 = Timer("from3bytes_array(s)", "from __main__ import s,
from3bytes_array")

print 'ord:\t', t1.timeit(1000)
print 'struct:\t', t2.timeit(1000)
print 'array:\t', t3.timeit(1000)

Output:
ord: 7.08213110884
struct: 3.7689164405
array: 2.62995268952

Inspired by Guido's essayhttp://www.python.org/doc/essays/list2str/
And even faster:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()

I think it's a fastest possible implementation in pure python
Jun 27 '08 #22
Ivan Illarionov wrote:
And even faster:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()

I think it's a fastest possible implementation in pure python
Clever, but note that it doesn't work correctly for negative numbers. For
those you'd have to prepend "\xff" instead of "\0".

Peter

Jun 27 '08 #23
On 2008-04-21 14:50:13 -0600, Ivan Illarionov <iv*************@gmail.comsaid:
On 22 апр, 00:10, Ivan Illarionov <ivan.illario...@gmail.com wrote:
>On 20 ÁÐÒ, 04:10, George Sakkis <george.sak...@gmail.comw
rote:
>>

>>On Apr 18, 9:36 pm, Ross Ridge <rri...@caffeine.csclub.uwaterloo.ca>
wrote:
>>>Ross Ridge <rri...@caffeine.csclub.uwaterloo.casaid:
>>>>If you have Python 2.5, here's a faster version:
>>>>from struct import *
unpack_i32be = Struct(">l").unpack
>>>>def from3Bytes_ross2(s):
return unpack_i32be(s + "\0")[0] >8
>>>Bob Greschke <b...@passcal.nmt.eduwrote:
>>>>That's not even intelligible. I wanna go back to COBOL. :)
>>>It's the same as the previous version except that it "precompiles"
the struct.unpack() format string. It works similar to the way Python
>>>handles regular expressions.
>>I didn't know about the Struct class; pretty neat. It's amazing that
this version without Psyco is as fast Bob's version with Psyco! Adding
Psyco to it though makes it *slower*, not faster. So here's how I'd
write it (if I wanted or had to stay in pure Python):
>>try: import psyco
except ImportError:
from struct import Struct
unpack_i32be = Struct(">l").unpack
def from3Bytes(s):
return unpack_i32be(s + "\0")[0] >8
else:
def from3Bytes(s):
Value = (ord(s[0])<<16) + (ord(s[1])<<8) + ord(s[2])
if Value >= 0x800000:
Value -= 0x1000000
return Value
psyco.bind(from3Bytes)
>>HTH,
George

I was able to get even faster pure-python version using array module:

a = array.array('l', ''.join(('\0' + s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()

It actually moves bytes around on C level.

test code:
import struct
import array
import sys

unpack_i32be = struct.Struct(">l").unpack
s = ''.join(struct.pack('>i', 1234567)[1:]*1000)

def from3bytes_ord(s):
values = []
for i in xrange(0, len(s), 3):
Value = (ord(s[i])<<16) | (ord(s[i+1])<<8) | ord(s[i+2])
if Value >= 0x800000:
Value -= 0x1000000
values.append(Value)
return values

def from3bytes_struct(s):
return [unpack_i32be(s[i:i+3] + "\0")[0] >8 for i in xrange(0,
len(s), 3)]

def from3bytes_array(s):
a = array.array('l', ''.join(('\0' + s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
return a.tolist()

from timeit import Timer

t1 = Timer("from3bytes_ord(s)", "from __main__ import s,
from3bytes_ord")
t2 = Timer("from3bytes_struct(s)", "from __main__ import s,
from3bytes_struct")
t3 = Timer("from3bytes_array(s)", "from __main__ import s,
from3bytes_array")

print 'ord:\t', t1.timeit(1000)
print 'struct:\t', t2.timeit(1000)
print 'array:\t', t3.timeit(1000)

Output:
ord: 7.08213110884
struct: 3.7689164405
array: 2.62995268952

Inspired by Guido's essayhttp://www.python.org/doc/essays/list2str/

And even faster:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()

I think it's a fastest possible implementation in pure python
Geeze! :) How did struct get so fast? I'm guessing there have been
improvements since 2.3 (which is what I've been working on). I'm going
to be able to go back to my IBM PC XT pretty soon. :)

Thanks!

Jun 27 '08 #24
Bob Greschke wrote:
On 2008-04-21 14:50:13 -0600, Ivan Illarionov <iv*************@gmail.comsaid:
>On 22 апр, 00:10, Ivan Illarionov <ivan.illario...@gmail.com wrote:
>>On 20 ÁÐÒ, 04:10, George Sakkis <george.sak...@gmail.comw
rote:
>>>

On Apr 18, 9:36 pm, Ross Ridge <rri...@caffeine.csclub.uwaterloo.ca>
wrote:
Ross Ridge <rri...@caffeine.csclub.uwaterloo.casaid:
>If you have Python 2.5, here's a faster version:
>from struct import *
>unpack_i32be = Struct(">l").unpack
>def from3Bytes_ross2(s):
>return unpack_i32be(s + "\0")[0] >8
Bob Greschke <b...@passcal.nmt.eduwrote:
>That's not even intelligible. I wanna go back to COBOL. :)
It's the same as the previous version except that it "precompiles"
the struct.unpack() format string. It works similar to the way Python
handles regular expressions.
I didn't know about the Struct class; pretty neat. It's amazing that
this version without Psyco is as fast Bob's version with Psyco! Adding
Psyco to it though makes it *slower*, not faster. So here's how I'd
write it (if I wanted or had to stay in pure Python):
try: import psyco
except ImportError:
from struct import Struct
unpack_i32be = Struct(">l").unpack
def from3Bytes(s):
return unpack_i32be(s + "\0")[0] >8
else:
def from3Bytes(s):
Value = (ord(s[0])<<16) + (ord(s[1])<<8) + ord(s[2])
if Value >= 0x800000:
Value -= 0x1000000
return Value
psyco.bind(from3Bytes)
HTH,
George
I was able to get even faster pure-python version using array module:

a = array.array('l', ''.join(('\0' + s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()

It actually moves bytes around on C level.

test code:
import struct
import array
import sys

unpack_i32be = struct.Struct(">l").unpack
s = ''.join(struct.pack('>i', 1234567)[1:]*1000)

def from3bytes_ord(s):
values = []
for i in xrange(0, len(s), 3):
Value = (ord(s[i])<<16) | (ord(s[i+1])<<8) | ord(s[i+2])
if Value >= 0x800000:
Value -= 0x1000000
values.append(Value)
return values

def from3bytes_struct(s):
return [unpack_i32be(s[i:i+3] + "\0")[0] >8 for i in xrange(0,
len(s), 3)]

def from3bytes_array(s):
a = array.array('l', ''.join(('\0' + s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
return a.tolist()

from timeit import Timer

t1 = Timer("from3bytes_ord(s)", "from __main__ import s,
from3bytes_ord")
t2 = Timer("from3bytes_struct(s)", "from __main__ import s,
from3bytes_struct")
t3 = Timer("from3bytes_array(s)", "from __main__ import s,
from3bytes_array")

print 'ord:\t', t1.timeit(1000)
print 'struct:\t', t2.timeit(1000)
print 'array:\t', t3.timeit(1000)

Output:
ord: 7.08213110884
struct: 3.7689164405
array: 2.62995268952

Inspired by Guido's essayhttp://www.python.org/doc/essays/list2str/
And even faster:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()

I think it's a fastest possible implementation in pure python

Geeze! :) How did struct get so fast? I'm guessing there have been
improvements since 2.3 (which is what I've been working on). I'm going
to be able to go back to my IBM PC XT pretty soon. :)

Thanks!
Yes, Bob Ippolito spent quite a bit of time improving it at the Need for
Speed sprint shortly before the 2.4 (?) release. It shows.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Jun 27 '08 #25
On 22 , 01:01, Peter Otten <__pete...@web.dewrote:
Ivan Illarionov wrote:
And even faster:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
I think it's a fastest possible implementation in pure python

Clever, but note that it doesn't work correctly for negative numbers. For
those you'd have to prepend "\xff" instead of "\0".

Peter
Thanks for correction.

Another step is needed:

a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
result = [n if n < 0x800000 else n - 0x1000000 for n in a]

And it's still pretty fast :)
Jun 27 '08 #26
Something is fishy. I just ran this simple-minded thing and I'm,
again, getting better times for ord() than I am for unpack() on a
2.8GHz OSX iMac with 2.5.1. This is the iterate so many times you can
use your wristwatch method:

----

#! /usr/bin/env python

from os import system
from struct import unpack

print "unpack 1"
system("date")
for x in xrange(0, 100000000):
Value = unpack(">B", "a")
system("date")
print

print "ord 1"
system("date")
for x in xrange(0, 100000000):
Value = ord("a")
system("date")
print

print "unpack 3"
system("date")
for x in xrange(0, 100000000):
Value = unpack(">BBB", "abc")
system("date")
print

print "ord 3"
system("date")
for x in xrange(0, 100000000):
Value = (ord("a") << 16)+(ord("b") << 8)+ord("c")
system("date")
----

Unpack 1 is about 1m20s
Ord 1 is about 20s
Unpack 3 is about 1m20s
Ord 3 is about 1m03s
after averaging a few runs.

Jun 27 '08 #27
On 2008-04-21 16:51:13 -0600, Bob Greschke <bo*@passcal.nmt.edusaid:
JUST COMPLETELY IGNORE THAT LAST ONE. What a dope. Here:

#! /usr/bin/env python

from os import system
from struct import unpack

print "unpack 1"
system("date")
for x in xrange(0, 100000000):
Value = unpack(">B", "a")[0]
if Value 0x800000:
Value -= 0x1000000
system("date")
print

print "ord 1"
system("date")
for x in xrange(0, 100000000):
Value = ord("a")
if Value 0x800000:
Value -= 0x1000000
system("date")
print

print "unpack 3"
system("date")
for x in xrange(0, 100000000):
Value1, Value2, Value3 = unpack(">BBB", "abc")
Value = (Value1 << 16)+(Value2 << 8)+Value3
if Value 0x800000:
Value -= 0x1000000
system("date")
print

print "ord 3"
system("date")
for x in xrange(0, 100000000):
Value = (ord("a") << 16)+(ord("b") << 8)+ord("c")
if Value 0x800000:
Value -= 0x1000000
system("date")
Still, the differences between unpack and ord are significant (I just
threw in the if's for fun).
Jun 27 '08 #28
On Apr 21, 5:30 pm, Ivan Illarionov <ivan.illario...@gmail.comwrote:
On 22 , 01:01, Peter Otten <__pete...@web.dewrote:
Ivan Illarionov wrote:
And even faster:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
I think it's a fastest possible implementation in pure python
Clever, but note that it doesn't work correctly for negative numbers. For
those you'd have to prepend "\xff" instead of "\0".
Peter

Thanks for correction.

Another step is needed:

a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
result = [n if n < 0x800000 else n - 0x1000000 for n in a]

And it's still pretty fast :)
Indeed, the array idea is paying off for largeish inputs. On my box
(Python 2.5, WinXP, 2GHz Intel Core Duo), the cutoff point where
from3Bytes_array becomes faster than from3Bytes_struct is close to 150
numbers (=450 bytes).

The struct solution though is now almost twice as fast with Psyco
enabled, while the array doesn't benefit from it. Here are some
numbers from a sample run:

*** Without Psyco ***
size=1
from3Bytes_ord: 0.033493
from3Bytes_struct: 0.018420
from3Bytes_array: 0.089735
size=10
from3Bytes_ord: 0.140470
from3Bytes_struct: 0.082326
from3Bytes_array: 0.142459
size=100
from3Bytes_ord: 1.180831
from3Bytes_struct: 0.664799
from3Bytes_array: 0.690315
size=1000
from3Bytes_ord: 11.551990
from3Bytes_struct: 6.390999
from3Bytes_array: 5.781636
*** With Psyco ***
size=1
from3Bytes_ord: 0.039287
from3Bytes_struct: 0.009453
from3Bytes_array: 0.098512
size=10
from3Bytes_ord: 0.174362
from3Bytes_struct: 0.045785
from3Bytes_array: 0.162171
size=100
from3Bytes_ord: 1.437203
from3Bytes_struct: 0.355930
from3Bytes_array: 0.800527
size=1000
from3Bytes_ord: 14.248668
from3Bytes_struct: 3.331309
from3Bytes_array: 6.946709
And here's the benchmark script:

import struct
from array import array

def from3Bytes_ord(s):
return [n if n<0x800000 else n-0x1000000 for n in
((ord(s[i])<<16) | (ord(s[i+1])<<8) | ord(s[i+2])
for i in xrange(0, len(s), 3))]

unpack_i32be = struct.Struct('>l').unpack
def from3Bytes_struct(s):
return [unpack_i32be(s[i:i+3] + '\0')[0]>>8
for i in xrange(0,len(s),3)]

def from3Bytes_array(s):
a = array('l', ''.join('\0' + s[i:i+3]
for i in xrange(0,len(s), 3)))
a.byteswap()
return [n if n<0x800000 else n-0x1000000 for n in a]
def benchmark():
from timeit import Timer
for n in 1,10,100,1000:
print ' size=%d' % n
# cycle between positive and negative
buf = ''.join(struct.pack('>i', 1234567*(-1)**(i%2))[1:]
for i in xrange(n))
for func in 'from3Bytes_ord', 'from3Bytes_struct',
'from3Bytes_array':
print ' %s: %f' % (func,
Timer('%s(buf)' % func ,
'from __main__ import %s; buf=%r' % (func,buf)
).timeit(10000))
if __name__ == '__main__':
s = ''.join(struct.pack('>i',v)[1:] for v in
[0,1,-2,500,-500,7777,-7777,-94496,98765,
-98765,8388607,-8388607,-8388608,1234567])
assert from3Bytes_ord(s) == from3Bytes_struct(s) ==
from3Bytes_array(s)

print '*** Without Psyco ***'
benchmark()

import psyco; psyco.full()
print '*** With Psyco ***'
benchmark()
George
Jun 27 '08 #29
On 2008-04-21 17:06:39 -0600, Bob Greschke <bo*@passcal.nmt.edusaid:
On 2008-04-21 16:51:13 -0600, Bob Greschke <bo*@passcal.nmt.edusaid:
JUST COMPLETELY IGNORE THAT LAST ONE. What a dope. Here:

#! /usr/bin/env python

from os import system
from struct import unpack

print "unpack 1"
system("date")
for x in xrange(0, 100000000):
Value = unpack(">B", "a")[0]
if Value 0x800000:
Value -= 0x1000000
system("date")
print

print "ord 1"
system("date")
for x in xrange(0, 100000000):
Value = ord("a")
if Value 0x800000:
Value -= 0x1000000
system("date")
print

print "unpack 3"
system("date")
for x in xrange(0, 100000000):
Value1, Value2, Value3 = unpack(">BBB", "abc")
Value = (Value1 << 16)+(Value2 << 8)+Value3
if Value 0x800000:
Value -= 0x1000000
system("date")
print

print "ord 3"
system("date")
for x in xrange(0, 100000000):
Value = (ord("a") << 16)+(ord("b") << 8)+ord("c")
if Value 0x800000:
Value -= 0x1000000
system("date")
Still, the differences between unpack and ord are significant (I just
threw in the if's for fun).
I just ran this on my SunBlade 1000 with 2.3.4 and

unpack 1: 7m53s
ord 1: 2m00s
unpack 3: 14m20s
ord 3: 5m30s

timeit looks broken somehow to me.

Jun 27 '08 #30
On Mon, 21 Apr 2008 16:10:05 -0700, George Sakkis wrote:
On Apr 21, 5:30 pm, Ivan Illarionov <ivan.illario...@gmail.comwrote:
>On 22 ÁÐÒ, 01:01, Peter Otten <__pete...@web.dewrote:
Ivan Illarionov wrote:
And even faster:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
I think it's a fastest possible implementation in pure python
Clever, but note that it doesn't work correctly for negative numbers.
For those you'd have to prepend "\xff" instead of "\0".
Peter

Thanks for correction.

Another step is needed:

a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
result = [n if n < 0x800000 else n - 0x1000000 for n in a]

And it's still pretty fast :)

Indeed, the array idea is paying off for largeish inputs. On my box
(Python 2.5, WinXP, 2GHz Intel Core Duo), the cutoff point where
from3Bytes_array becomes faster than from3Bytes_struct is close to 150
numbers (=450 bytes).

The struct solution though is now almost twice as fast with Psyco
enabled, while the array doesn't benefit from it. Here are some numbers
from a sample run:

*** Without Psyco ***
size=1
from3Bytes_ord: 0.033493
from3Bytes_struct: 0.018420
from3Bytes_array: 0.089735
size=10
from3Bytes_ord: 0.140470
from3Bytes_struct: 0.082326
from3Bytes_array: 0.142459
size=100
from3Bytes_ord: 1.180831
from3Bytes_struct: 0.664799
from3Bytes_array: 0.690315
size=1000
from3Bytes_ord: 11.551990
from3Bytes_struct: 6.390999
from3Bytes_array: 5.781636
*** With Psyco ***
size=1
from3Bytes_ord: 0.039287
from3Bytes_struct: 0.009453
from3Bytes_array: 0.098512
size=10
from3Bytes_ord: 0.174362
from3Bytes_struct: 0.045785
from3Bytes_array: 0.162171
size=100
from3Bytes_ord: 1.437203
from3Bytes_struct: 0.355930
from3Bytes_array: 0.800527
size=1000
from3Bytes_ord: 14.248668
from3Bytes_struct: 3.331309
from3Bytes_array: 6.946709
And here's the benchmark script:

import struct
from array import array

def from3Bytes_ord(s):
return [n if n<0x800000 else n-0x1000000 for n in
((ord(s[i])<<16) | (ord(s[i+1])<<8) | ord(s[i+2])
for i in xrange(0, len(s), 3))]

unpack_i32be = struct.Struct('>l').unpack def from3Bytes_struct(s):
return [unpack_i32be(s[i:i+3] + '\0')[0]>>8
for i in xrange(0,len(s),3)]

def from3Bytes_array(s):
a = array('l', ''.join('\0' + s[i:i+3]
for i in xrange(0,len(s), 3)))
a.byteswap()
return [n if n<0x800000 else n-0x1000000 for n in a]
def benchmark():
from timeit import Timer
for n in 1,10,100,1000:
print ' size=%d' % n
# cycle between positive and negative buf =
''.join(struct.pack('>i', 1234567*(-1)**(i%2))[1:]
for i in xrange(n))
for func in 'from3Bytes_ord', 'from3Bytes_struct',
'from3Bytes_array':
print ' %s: %f' % (func,
Timer('%s(buf)' % func ,
'from __main__ import %s; buf=%r' % (func,buf)
).timeit(10000))
if __name__ == '__main__':
s = ''.join(struct.pack('>i',v)[1:] for v in
[0,1,-2,500,-500,7777,-7777,-94496,98765,
-98765,8388607,-8388607,-8388608,1234567])
assert from3Bytes_ord(s) == from3Bytes_struct(s) ==
from3Bytes_array(s)

print '*** Without Psyco ***'
benchmark()

import psyco; psyco.full()
print '*** With Psyco ***'
benchmark()
George
Comments:
You didn't use the faster version of array approach:
''.join('\0' + s[i:i+3] for i in xrange(0,len(s), 3))
is slower than
'\0' + '\0'.join(s[i:i+3] for i in xrange(0,len(s), 3))
To Bob Greschke:

Struct is fast in Python 2.5 with struct.Struct class.

Array approach should work with Python 2.3 and it's probably the fastest
one (without psyco) with large inputs:

def from3bytes_array(s):
a = array.array('i', '\0' + '\0'.join([s[i:i+3]
for i in xrange(0, len(s), 3)]))
a.byteswap() # if your system is little-endian
return [n >= 0x800000 and n - 0x1000000 or n for n in a]

--
Ivan
Jun 27 '08 #31
On Mon, 21 Apr 2008 16:10:05 -0700, George Sakkis wrote:
On Apr 21, 5:30 pm, Ivan Illarionov <ivan.illario...@gmail.comwrote:
>On 22 ÁÐÒ, 01:01, Peter Otten <__pete...@web.dewrote:
Ivan Illarionov wrote:
And even faster:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
I think it's a fastest possible implementation in pure python
Clever, but note that it doesn't work correctly for negative numbers.
For those you'd have to prepend "\xff" instead of "\0".
Peter

Thanks for correction.

Another step is needed:

a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
a.byteswap()
result = [n if n < 0x800000 else n - 0x1000000 for n in a]

And it's still pretty fast :)

Indeed, the array idea is paying off for largeish inputs. On my box
(Python 2.5, WinXP, 2GHz Intel Core Duo), the cutoff point where
from3Bytes_array becomes faster than from3Bytes_struct is close to 150
numbers (=450 bytes).

The struct solution though is now almost twice as fast with Psyco
enabled, while the array doesn't benefit from it. Here are some numbers
from a sample run:

*** Without Psyco ***
size=1
from3Bytes_ord: 0.033493
from3Bytes_struct: 0.018420
from3Bytes_array: 0.089735
size=10
from3Bytes_ord: 0.140470
from3Bytes_struct: 0.082326
from3Bytes_array: 0.142459
size=100
from3Bytes_ord: 1.180831
from3Bytes_struct: 0.664799
from3Bytes_array: 0.690315
size=1000
from3Bytes_ord: 11.551990
from3Bytes_struct: 6.390999
from3Bytes_array: 5.781636
*** With Psyco ***
size=1
from3Bytes_ord: 0.039287
from3Bytes_struct: 0.009453
from3Bytes_array: 0.098512
size=10
from3Bytes_ord: 0.174362
from3Bytes_struct: 0.045785
from3Bytes_array: 0.162171
size=100
from3Bytes_ord: 1.437203
from3Bytes_struct: 0.355930
from3Bytes_array: 0.800527
size=1000
from3Bytes_ord: 14.248668
from3Bytes_struct: 3.331309
from3Bytes_array: 6.946709
And here's the benchmark script:

import struct
from array import array

def from3Bytes_ord(s):
return [n if n<0x800000 else n-0x1000000 for n in
((ord(s[i])<<16) | (ord(s[i+1])<<8) | ord(s[i+2])
for i in xrange(0, len(s), 3))]

unpack_i32be = struct.Struct('>l').unpack def from3Bytes_struct(s):
return [unpack_i32be(s[i:i+3] + '\0')[0]>>8
for i in xrange(0,len(s),3)]

def from3Bytes_array(s):
a = array('l', ''.join('\0' + s[i:i+3]
for i in xrange(0,len(s), 3)))
a.byteswap()
return [n if n<0x800000 else n-0x1000000 for n in a]
def benchmark():
from timeit import Timer
for n in 1,10,100,1000:
print ' size=%d' % n
# cycle between positive and negative buf =
''.join(struct.pack('>i', 1234567*(-1)**(i%2))[1:]
for i in xrange(n))
for func in 'from3Bytes_ord', 'from3Bytes_struct',
'from3Bytes_array':
print ' %s: %f' % (func,
Timer('%s(buf)' % func ,
'from __main__ import %s; buf=%r' % (func,buf)
).timeit(10000))
if __name__ == '__main__':
s = ''.join(struct.pack('>i',v)[1:] for v in
[0,1,-2,500,-500,7777,-7777,-94496,98765,
-98765,8388607,-8388607,-8388608,1234567])
assert from3Bytes_ord(s) == from3Bytes_struct(s) ==
from3Bytes_array(s)

print '*** Without Psyco ***'
benchmark()

import psyco; psyco.full()
print '*** With Psyco ***'
benchmark()
George
Comments:
You didn't use the faster version of array approach:
''.join('\0' + s[i:i+3] for i in xrange(0,len(s), 3))
is slower than
'\0' + '\0'.join(s[i:i+3] for i in xrange(0,len(s), 3))
To Bob Greschke:

Struct is fast in Python 2.5 with struct.Struct class.

Array approach should work with Python 2.3 and it's probably the fastest
one (without psyco) with large inputs:

def from3bytes_array(s):
a = array.array('i', '\0' + '\0'.join([s[i:i+3]
for i in xrange(0, len(s), 3)]))
a.byteswap() # if your system is little-endian
return [n >= 0x800000 and n - 0x1000000 or n for n in a]

--
Ivan
Jun 27 '08 #32
On Apr 22, 12:04*am, Ivan Illarionov <ivan.illario...@gmail.com>
wrote:
On Mon, 21 Apr 2008 16:10:05 -0700, George Sakkis wrote:
On Apr 21, 5:30 pm, Ivan Illarionov <ivan.illario...@gmail.comwrote:
On 22 , 01:01, Peter Otten <__pete...@web.dewrote:
Ivan Illarionov wrote:
And even faster:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
* * a.byteswap()
I think it's a fastest possible implementation in pure python
Clever, but note that it doesn't work correctly for negative numbers.
For those you'd have to prepend "\xff" instead of "\0".
Peter
Thanks for correction.
Another step is needed:
a = array.array('i', '\0' + '\0'.join((s[i:i+3] for i in xrange(0,
len(s), 3))))
if sys.byteorder == 'little':
* * a.byteswap()
result = [n if n < 0x800000 else n - 0x1000000 for n in a]
And it's still pretty fast :)
Indeed, the array idea is paying off for largeish inputs. On my box
(Python 2.5, WinXP, 2GHz Intel Core Duo), the cutoff point where
from3Bytes_array becomes faster than from3Bytes_struct is close to 150
numbers (=450 bytes).
The struct solution though is now almost twice as fast with Psyco
enabled, while the array doesn't benefit from it. Here are some numbers
from a sample run:
*** Without Psyco ***
* size=1
* * from3Bytes_ord: 0.033493
* * from3Bytes_struct: 0.018420
* * from3Bytes_array: 0.089735
* size=10
* * from3Bytes_ord: 0.140470
* * from3Bytes_struct: 0.082326
* * from3Bytes_array: 0.142459
* size=100
* * from3Bytes_ord: 1.180831
* * from3Bytes_struct: 0.664799
* * from3Bytes_array: 0.690315
* size=1000
* * from3Bytes_ord: 11.551990
* * from3Bytes_struct: 6.390999
* * from3Bytes_array: 5.781636
*** With Psyco ***
* size=1
* * from3Bytes_ord: 0.039287
* * from3Bytes_struct: 0.009453
* * from3Bytes_array: 0.098512
* size=10
* * from3Bytes_ord: 0.174362
* * from3Bytes_struct: 0.045785
* * from3Bytes_array: 0.162171
* size=100
* * from3Bytes_ord: 1.437203
* * from3Bytes_struct: 0.355930
* * from3Bytes_array: 0.800527
* size=1000
* * from3Bytes_ord: 14.248668
* * from3Bytes_struct: 3.331309
* * from3Bytes_array: 6.946709
And here's the benchmark script:
import struct
from array import array
def from3Bytes_ord(s):
* * return [n if n<0x800000 else n-0x1000000 for n in
* * * * * * ((ord(s[i])<<16) | (ord(s[i+1])<<8) | ord(s[i+2])
* * * * * * * for i in xrange(0, len(s), 3))]
unpack_i32be = struct.Struct('>l').unpack def from3Bytes_struct(s):
* * return [unpack_i32be(s[i:i+3] + '\0')[0]>>8
* * * * * * for i in xrange(0,len(s),3)]
def from3Bytes_array(s):
* * a = array('l', ''.join('\0' + s[i:i+3]
* * * * * * * * * * * * * *for i in xrange(0,len(s), 3)))
* * a.byteswap()
* * return [n if n<0x800000 else n-0x1000000 for n in a]
def benchmark():
* * from timeit import Timer
* * for n in 1,10,100,1000:
* * * * print ' *size=%d' % n
* * * * # cycle between positive and negative buf =
* * * * ''.join(struct.pack('>i', 1234567*(-1)**(i%2))[1:]
* * * * * * * * * * * for i in xrange(n))
* * * * for func in 'from3Bytes_ord', 'from3Bytes_struct',
'from3Bytes_array':
* * * * * * print ' * *%s: %f' % (func,
* * * * * * * * Timer('%s(buf)' % func ,
* * * * * * * * * * * 'from __main__ import %s; buf=%r' % (func,buf)
* * * * * * * * * * * ).timeit(10000))
if __name__ == '__main__':
* * s = ''.join(struct.pack('>i',v)[1:] for v in
* * * * * * * * [0,1,-2,500,-500,7777,-7777,-94496,98765,
* * * * * * * * -98765,8388607,-8388607,-8388608,1234567])
* * assert from3Bytes_ord(s) == from3Bytes_struct(s) ==
from3Bytes_array(s)
* * print '*** Without Psyco ***'
* * benchmark()
* * import psyco; psyco.full()
* * print '*** With Psyco ***'
* * benchmark()
George

Comments:
You didn't use the faster version of array approach:
''.join('\0' + s[i:i+3] for i in xrange(0,len(s), 3))
is slower than
'\0' + '\0'.join(s[i:i+3] for i in xrange(0,len(s), 3))
Good catch; the faster version reduces the cutoff point between
from3Bytes_array and from3Bytes_struct to ~50 numbers (=150 bytes)
only (without Psyco).

George
Jun 27 '08 #33

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

Similar topics

17
by: Asfand Yar Qazi | last post by:
Basically this: //file 'B.hh' class B { protected: void f() {} }; //file 'C.hh'
1
by: Viken Karaguesian | last post by:
Hello all, I'm taking a shot at table-less design, but I feel like I'm poking in the dark here. I decided to try and recreate the main page of a webiste that I run, www.sayatnova.com, using CSS...
9
by: Ook | last post by:
I need a function that swaps arguements. This is my function. It works, after calling swapArgs aa now has 321, and bb has 123. My question - did I do it right? Just because it works doesn't mean I...
2
by: Abby | last post by:
I need to do 8 bits 2's complement checksum, so I wrote code in order to see if the checksum calculation is correct. ===========================================================================...
6
by: Neo Geshel | last post by:
Greetings. I am making an admin interface, which allows me to upload photos to an access DB. The admin interface also needs to display the uploaded photos, but only needs to show them at a...
3
by: J-T | last post by:
Is there a problem of defining a category object like below. I am just trying to create a proof-of-concept sort of application (and I don't want to use database) , so I have to sort of hard code...
0
by: Chris | last post by:
I am getting a bit confused again with theis com+ stuff. I am looking at the PetShop app and I see the layers BLL DAL. Do these layers have to be on the same web server? If they are on separate...
0
by: Satheshkumar | last post by:
Dear Sir/Madam, I am Sathesh, i am working as a Software Engineer in one software concern. In my project work, I will need to install the Microsoft .NET FrameWork1.1 and Microsoft VJ#...
11
by: Lou Pecora | last post by:
From what I gleaned on some messages this is the way multiple imports of the same module work. Say, I have 3 modules (mod1.py, mod2.py, and mod3.py) and in the same session they all import another...
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
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
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...
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing,...

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.