On 19-04-16 10:21, Elizabeth Mattijsen wrote:
FWIW, I’ll take PR’s for the PackUnpack distribution to make ‘f’ and ‘d’ work
:-)
Hi Elizabeth,
For the PackUnpack distro this might come in handy... or might go in the
examples corner?
Done some experiments and looks well. Please check the attachment for
encoding/decoding of doubles. decode-double has also an index in the
buffer to pull out a specific spot in the buffer where the encoded
double should be. The code is made from snippets from Timo Paulsen and
David Warren.
You might want to know how much faster it has become. Well it's not that
much of an improvement, only encoding a double is about 4 times faster.
The decoding only 1.13 times.
emulated encoded
3000 runs total time = 7.211524 s, 0.002404 s per run, 416.000809 runs per s
native encoded
3000 runs total time = 1.720918 s, 0.000574 s per run, 1743.256109 runs
per s
emulated decode
3000 runs total time = 1.038615 s, 0.000346 s per run, 2888.461538 runs
per s
native decode
3000 runs total time = 0.918133 s, 0.000306 s per run, 3267.498734 runs
per s
Before I pat myself on the back for the 'fast' emulated encode/decode
already in place in the BSON package the above results might mean that
the native routines can be done better.
Regards,
Marcel
#!/usr/bin/env perl6
use v6.c;
use NativeCall;
say 'little endian: ', little-endian;
for ( 0.3e3, 0.233333333, -20.45e-20, Inf, NaN) -> $r {
say "Encode $r";
my Buf $b = encode-double(Num.new($r));
say $b.list.fmt('%02x');
say "Decoded num = ", decode-double( $b, 0);
}
#-----------------------------------------------------------------------------
# encode Num in buf little endian
#
sub encode-double ( Num:D $r --> Buf ) {
my CArray[num64] $da .= new($r);
my $list = nativecast( CArray[uint8], $da)[^8];
if little-endian() {
Buf[uint8].new($list);
}
else {
Buf[uint8].new($list.reverse);
}
}
#-----------------------------------------------------------------------------
# decode to Num from buf little endian
#
sub decode-double ( Buf:D $b, Int:D $index --> Num ) {
my Buf[uint8] $ble;
my $list = $b.list;
if little-endian() {
$ble .= new($b.subbuf( $index, 8));
}
else {
$ble .= new($b.subbuf( $index, 8).reverse);
}
nativecast( CArray[num64], $ble)[0];
}
#-----------------------------------------------------------------------------
sub little-endian ( --> Bool ) {
my $i = CArray[uint32].new: 1;
my $j = nativecast( CArray[uint8], $i);
$j[0] == 0x01;
}