аналоги bitpacked в других языках?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

аналоги bitpacked в других языках?

Сообщение xdsl » 22.10.2015 10:02:15

Вот просто интересно. На паскале пишу
Код: Выделить всё
var X:double;
    Y:bitpacked array[0..sizeof(x)*8-1] of 0..1 absolute X;

И потом спокойно ковыряю битовый массив Y на предмет особенностей IEEE 754, проверяя результаты в переменной X.

Вопрос: в других языках есть столь-же простой метод? Чисто языковыми средствами, в пару строк, без запарок с классами-объектами?

Добавлено спустя 1 час 33 минуты 24 секунды:
Нда, решил проверить хваленый bitset из С++. Забиваю 500 миллионов бит единицами, потом в середине диапазона проверяю, нулю один бит, снова проверяю.
Результат - сливает bitset паскалю вчистую:
test.cpp
Код: Выделить всё
#include <iostream>
#include <bitset>
using namespace std;
#define size 500000000
bitset<size> test;

int main()
{
long i;
for (i=0;i<size;i++)test[i]=1;
cout<<test[size/2]<<endl;
test[size/2]=0;
cout<<test[size/2]<<endl;
return 0;
}

Компилируем: g++ test.cpp -o test_cpp
Запускаем: time ./test_cpp
Получаем на моей машине:
Код: Выделить всё
1
0
13.98user 0.04system 0:14.05elapsed 99%CPU (0avgtext+0avgdata 62192maxresident)k
0inputs+0outputs (0major+15607minor)pagefaults 0swaps

Теперь на паскале:
test.pp
Код: Выделить всё
{$mode objfpc}
const size=500000000;
var test:bitpacked array[0..size]of 0..1;
    i:longint;
begin
for i:=0 to size-1 do test[i]:=1;
writeln(test[size div 2]);
test[size div 2]:=0;
writeln(test[size div 2]);
end.

Компилируем: fpc test.pp -otest_pp
Запускаем: time ./test_pp
Получаем на моей машине:
Код: Выделить всё
1
0
1.40user 0.07system 0:01.48elapsed 99%CPU (0avgtext+0avgdata 61132maxresident)k
0inputs+0outputs (0major+15748minor)pagefaults 0swaps

Полторы секунды против четырнадцати, разница по скорости - в 10 раз!
Может это только на моем 64-разрядном линуксе, но почему не думаю, что результаты будут особо отличаться на других осях и разрядах.
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03

Re: аналоги bitpacked в других языках?

Сообщение Дож » 22.10.2015 11:51:13

Боже, когда люди научаться аккуратно замерять производительность и анализировать результаты экспериментов, а не бежать сломя голову на форум делиться сенсациями?

Что будет, если Вы g++ будете запускать с опцией -O3?
Код: Выделить всё
$ g++ -O3 bitset.cpp -o bitset && time ./bitset
1
0

real    0m1.096s
user    0m1.060s
sys     0m0.036s


Или так (тестировал на своём ноутбуке):
Код: Выделить всё
C:\data\temp>type test.bat
g++ -O3 bitset.cpp -o bitset.exe
echo %time%
bitset.exe
echo %time%

fpc -O3 bitset_pas.pas
echo %time%
bitset_pas.exe
echo %time%

Код: Выделить всё
C:\data\temp>test.bat

C:\data\temp>g++ -O3 bitset.cpp -o bitset.exe

C:\data\temp>echo 10:50:27,67
10:50:27,67

C:\data\temp>bitset.exe
1
0

C:\data\temp>echo 10:50:28,67
10:50:28,67

C:\data\temp>fpc -O3 bitset_pas.pas
Free Pascal Compiler version 3.0.0rc1 [2015/08/10] for i386
Copyright (c) 1993-2015 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling bitset_pas.pas
Linking bitset_pas.exe
10 lines compiled, 0.1 sec, 25872 bytes code, 1268 bytes data

C:\data\temp>echo 10:50:28,83
10:50:28,83

C:\data\temp>bitset_pas.exe
1
0

C:\data\temp>echo 10:50:40,61
10:50:40,61
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: аналоги bitpacked в других языках?

Сообщение xdsl » 22.10.2015 15:47:58

Действительно, с опцией O3 скорости обработки оказались сопоставимы.

Про О1 еще помню, а про О3 совсем забыл. И про О2 забыл. И слава Богу, ибо и то и другое - верный способ угробить работающее приложение при перекомпиляции :wink:. Кто драйвера писал или просто с железом активно данными обменивался, меня поймет. А на каждый чих volatile не напасешься, особенно если приложение не твое. Поэтому вариант с высокоскоростным битсетом в сдохшем из-за оптимизации приложении меня не очень вдохновляет.

Тем не менее, исходный вопрос в силе: где еще есть битовые массивы, реализованные языковыми средствами? Вернее даже - многобитовые, т.к. каждый элемент массива может из нескольких битов состоять. Пока не нашел.
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03

Re: аналоги bitpacked в других языках?

Сообщение runewalsh » 22.10.2015 15:56:55

>sizeof(x)*8
Это назывется bitsizeof.

>аналоги bitpacked в других языках?
В C/C++ аналог твоего:
Код: Выделить всё
union double_bits
{
  double x;
  struct {
    unsigned int mantissa : 52;
    unsigned int exponent : 11;
    unsigned int sign : 1;
  } parts;
};

P.S. Поосторожнее с поиском преимуществ в паскале. Так люди знают только русский и при этом умудряются считать его самым-самым, мол, в других языках нет каких-то его средств или сложных языковых идиом, сравнимых по удобству, если не сказать больше. ;)
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Re: аналоги bitpacked в других языках?

Сообщение Kemet » 24.10.2015 13:58:09

а это Модула-3
Код: Выделить всё
(* This interface describes the layout of IEEE single precision reals
   on little endian machines *)
TYPE
  T = RECORD
    significand: BITS 23 FOR [16_0 .. 16_7fffff] := 0;
    exponent:    BITS  8 FOR [16_0 .. 16_ff]     := 0;
    sign:        BITS  1 FOR [16_0 .. 16_1]      := 0;
  END;
Kemet
постоялец
 
Сообщения: 241
Зарегистрирован: 10.02.2010 19:28:32
Откуда: Временно оккупированная территория

Re: аналоги bitpacked в других языках?

Сообщение xdsl » 28.10.2015 12:26:54

runewalsh писал(а):>sizeof(x)*8
Это назывется bitsizeof.

Спасибо, совсем забыл про эту функцию.

runewalsh писал(а):В C/C++ аналог твоего:
Код: Выделить всё
union double_bits
{
  double x;
  struct {
    unsigned int mantissa : 52;
    unsigned int exponent : 11;
    unsigned int sign : 1;
  } parts;
};


Немного не то. Как и пример с модулой. Я не ищу аналог bitpacked record, мне интересен аналог bitpacked array.
runewalsh писал(а):
P.S. Поосторожнее с поиском преимуществ в паскале. Так люди знают только русский и при этом умудряются считать его самым-самым, мол, в других языках нет каких-то его средств или сложных языковых идиом, сравнимых по удобству, если не сказать больше. ;)


Я не ищу преимуществ или недостатков, и то и другое мне известно достаточно хорошо. Мне интересны аналоги. Аналог bitpacked array пока не найден.
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03

Re: аналоги bitpacked в других языках?

Сообщение xdsl » 29.10.2015 22:14:53

Кстати, вот пример удобства использования bitpacked array. Буквально на коленке написанный кодировщик в Base64:
Код: Выделить всё
{$mode objfpc}
uses strutils;

const CMax=1000;
      Base64S='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
type T6bit=0..63;
     TBase64Array=bitpacked array[1..CMax]of T6bit;

function b64(s:AnsiString):Ansistring;
var x:^TBase64Array absolute s;
     first,i:integer;
begin
result:=''; first:=1;
while length(s) mod 3 <> 0 do begin s+=#0; inc(first); end;
s:=reverseString(s);
for i:=length(s)*4 div 3 downto first do result+=Base64s[x^[i]+1];
while first<>1 do begin dec(first); result+='='; end;
end;

var s:ansistring;
begin
readln(s);
writeln(b64(s));
end.


Вот и другой вариант, уже не на коленке, но тоже не сложный и при этом - быстрый:
Код: Выделить всё
{$mode objfpc}
const
  Base64S='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

function b64(const s:AnsiString):Ansistring;
var buf8:array[1..3] of char;
     buf6:bitpacked array[1..4] of 0..63 absolute buf8;
     i6,i,i8,lenS,index:integer;
begin
result:=''; index:=0; lenS:=length(s);
setLength(result,((lens-1)div 3+1)*4);

for i:=1 to lenS div 3 do begin
  for i8:=3 downto 1 do buf8[i8]:=s[3*i+1-i8];
  for i6:=4 downto 1 do begin inc(index); result[index]:=Base64s[buf6[i6]+1]; end;
end;

case lenS mod 3 of
  0: exit;
  1: begin
        buf8[1]:=#0;  buf8[2]:=#0;  buf8[3]:=s[lens];
        result[index+1]:=Base64s[buf6[4]+1];
        result[index+2]:=Base64s[buf6[3]+1];
        result[index+3]:='=';
        result[index+4]:='=';
    end;
  2: begin
        buf8[1]:=#0; buf8[2]:=s[lens]; buf8[3]:=s[lens-1];
        result[index+1]:=Base64s[buf6[4]+1];
        result[index+2]:=Base64s[buf6[3]+1];
        result[index+3]:=Base64s[buf6[2]+1];
        result[index+4]:='=';
    end;
end;
end;

var s:ansistring;
begin
readln(s);
writeln(b64(s));
end.


Второй вариант бьет по скорости в несколько раз кодировщик из модуля base64(http://www.freepascal.org/docs-html/fcl ... index.html) и сравним по скорости кодирования (специально для апологетов -O3), например, с этим http://www.adp-gmbh.ch/cpp/common/base64.html (без -O3 сишная программа сливает по скорости в несколько раз).

Впрочем, разговор не о скорости, а о простоте создания подобных программ. На мой взгляд - значительно проще, чем возиться с битовыми операциями.
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03

Re: аналоги bitpacked в других языках?

Сообщение runewalsh » 30.10.2015 07:33:35

xdsl писал(а):вот пример удобства использования bitpacked array. Буквально на коленке написанный кодировщик в Base64

Лол, гениально, стащу себе =3
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru