Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

byte-swapping: performance

88 views
Skip to first unread message

TM

unread,
Jan 24, 2013, 9:31:44 AM1/24/13
to
Hi,

What is the fastest way of coding byte-swapping?

if bvals is a long binary string of variable length: 12345678....
that I want to parse to: [list 0x3412 0x7856 ...]

Is it:

a)

for {set i 0} {$i < [string length $bvals]} {incr i 4} {
set val [string range $bvals $i [expr {$i + 3}]]
lappend lvals 0x[string range $val 2 3][string range $val 0 1]
}

b)

for {set i 0} {$i < [string length $bvals]} {incr i 4} {
set val 0x[string range $bvals $i [expr {$i + 3}]]
lappend lvals [format %x [expr {(($val & 0xff) << 8) + (($val & 0xff00) >> 8)}]]
}

c) None of the above

Thanks
TM

Uwe Klein

unread,
Jan 24, 2013, 10:28:42 AM1/24/13
to
use [ time $script $iterarions ] to find out ;-)

d)
assuming you actually have a string of numbers:
set list [ split $bvals {} }
foreach {a b c d} $list {
append res \ 0x $c $d $a $b
}
puts $res


if you have a buffer of shorts that you want to
byteorder change use [binary scan S* ( or s* )
depending on your host byte order.

uwe

TM

unread,
Jan 24, 2013, 11:17:45 AM1/24/13
to
Uwe,

Thanks for the tip. I'm going to measure the performance of the 3 options.

I am using [binary scan $bstring H* ...], but I'll try
[binary scan $bstring S* ...]

TM

TM

unread,
Jan 24, 2013, 12:03:38 PM1/24/13
to
I've tested the options.

[binary scan S* ...] doesn't work. I have to stick to [binary scan H* ...].

Within that constraint, these are the results:

binary scan $pkt H* data

1. ~280us
foreach {a b c d} [split $data {}] {
lappend out "0x${c}${d}${a}${b}"
}

2. ~330us
for {set j 0} {$j < [string length $data]} {incr j 4} {
set d 0x[string range $data $j [expr {$j + 3}]]
lappend out [expr {(($d & 0xff) << 8) + (($d & 0xff00) >> 8)}]
}

3. ~700us
for {set j 0} {$j < [string length $data]} {incr j 4} {
set point [string range $data [expr {$j + 2}] [expr {$j + 3}]][string range $data $j [expr {$j + 1}]]
lappend out 0x$point
}

Uwe, your suggestion is indeed the best solution, thanks for your help,

TM

Uwe Klein

unread,
Jan 24, 2013, 1:01:53 PM1/24/13
to
TM wrote:
> I've tested the options.
>
> [binary scan S* ...] doesn't work. I have to stick to [binary scan H* ...].

it should.
do you really need the numbers formatted 0x12ef or would
a list of ints be sufficient?

What do you do with the list you get ?

uwe
>
> Within that constraint, these are the results:
>
> binary scan $pkt H* data
>
> 1. ~280us
> foreach {a b c d} [split $data {}] {
> lappend out "0x${c}${d}${a}${b}"
> }
>
> 2. ~330us
> for {set j 0} {$j < [string length $data]} {incr j 4} {
> set d 0x[string range $data $j [expr {$j + 3}]]
> lappend out [expr {(($d & 0xff) << 8) + (($d & 0xff00) >> 8)}]
> }
>
> 3. ~700us
> for {set j 0} {$j < [string length $data]} {incr j 4} {
> set point [string range $data [expr {$j + 2}] [expr {$j + 3}]][string range $data $j [expr {$j + 1}]]
> lappend out 0x$point
> }
>
> Uwe, your suggestion is indeed the best solution, thanks for your help,
>
> TM
;-)
0 new messages