Страница 2 из 2
Re: Двоичное представление строки
Добавлено: 07.09.2015 22:12:29
runewalsh
zub писал(а):Проверку на нулевую длину никто не отменял.
Так длиннее. >_< Ну окей.
Тоже написал бенчмарк. В цикле соединяются по 3 строки, результат заведомо умещается в 255 символов.
Код: Выделить всё
{$mode objfpc}
{$coperators+}
{$macro+}
uses
SysUtils, DateUtils;
function RandomString: ansistring;
const
MinLen = 10;
var
i: SizeUint;
begin
SetLength(result, MinLen + random((256 - MinLen) div 3));
for i := 1 to length(result) do
result[i] := chr(ord('a') + random(ord('z') - ord('a') + 1));
end;
const
NStrings = 1000000;
Iterations = 15;
var
ss: array[0 .. NStrings - 1] of shortstring;
ss_concat: array[0 .. (NStrings + 1) div 3 - 1] of shortstring;
ls: array[0 .. NStrings - 1] of ansistring;
ls_concat: array[0 .. (NStrings + 1) div 3 - 1] of ansistring;
i, ci, iteration: integer;
dt: TDateTime;
ms: integer;
begin
write('Generating... (1/2) ');
for i := Low(ss) to High(ss) do
begin
ss[i] := RandomString;
if (i + 1) mod (length(ss) div 10) = 0 then write('#');
end;
writeln;
write(' (2/2) ');
for i := Low(ls) to High(ls) do
begin
ls[i] := RandomString;
if (i + 1) mod (length(ls) div 10) = 0 then write('#');
end;
writeln(' OK');
writeln;
{$define test :=
write('Testing ' + typename + '... ');
dt := Now;
for iteration := 0 to Iterations - 1 do
begin
i := iteration;
ci := 0;
while i + 2 <= High(strings_array) do
begin
concatenated_array[ci] := strings_array[i] + strings_array[i + 1] + strings_array[i + 2];
i += 3;
ci += 1;
end;
end;
ms := MillisecondsBetween(dt, Now);
writeln('avg. ', ms / (NStrings * Iterations) * 1e6:0:2, ' ns');
{$undef typename} {$undef strings_array} {$undef concatenated_array}}
{$define typename := 'ShortString'}
{$define strings_array := ss}
{$define concatenated_array := ss_concat}
test
{$define typename := 'AnsiString'}
{$define strings_array := ls}
{$define concatenated_array := ls_concat}
test
{$undef test}
end.
В худшем случае ansistring медленнее на 35%, в лучшем (достигается, если, например, в RandomString сделать постоянную длину) — вдвое быстрее, в общем, шортстринги себя не оправдывают, единственное преимущество — и то спорное.
Re: Двоичное представление строки
Добавлено: 07.09.2015 23:09:19
bormant
Pasha-V писал(а):Например строка 'World'. Как узнать ее двоичное представление? Есть функция по преобразованию?
Код: Выделить всё
procedure HexDump(var m; Count: Word);
const HD: array [0..$F] of Char = '0123456789ABCDEF';
var p: ^Byte;
begin
p:=@m;
while Count>0 do begin
Write(' ',HD[p^ shr 4],HD[p^ and $F]); Inc(p); Dec(Count);
end; WriteLn;
end;
const
s: String[9] = 'World';
begin
HexDump(s,SizeOf(s));
end.
Вывод:
Код: Выделить всё
05 57 6F 72 6C 64 20 20 20 20
длина W o r l d
Re: Двоичное представление строки
Добавлено: 08.09.2015 01:13:10
Pasha-V
В Release поровну
runewalsh, убедил, у меня такой же результат. Получается, что нужно всегда использовать Release? Вообще, чем он хуже, какие минусы?
Добавлено спустя 1 минуту 38 секунд:bormant, спасибо. Только я не профи и не понял: эти данные берутся непосредственно из памяти или это просто преобразование символов строки в их коды?
Re: Двоичное представление строки
Добавлено: 08.09.2015 06:01:44
sign
Re: Двоичное представление строки
Добавлено: 08.09.2015 09:10:35
bormant
Pasha-V писал(а):Только я не профи и не понял: эти данные берутся непосредственно из памяти или это просто преобразование символов строки в их коды?
Процедура HexDump выводит шестнадцатеричный дамп участка памяти длиной Count, начиная с адреса первого параметра (m). Поэтому для вызова мы видим, что в памяти лежит длина строки 5, следом 5 символов (да, это коды символов в 16-ричном виде) и следом мусор (компилятор дополнил типизированную константу пробелами $20, но обычно нужно ожидать там мусор).
Добавлено спустя 3 минуты 30 секунд:sign,
Вот только одному мне кажется, что вывели вы не содержимое строки, а хранящийся в s указатель на динамическую строку? С ShortString да, было бы содержимое строки.
Re: Двоичное представление строки
Добавлено: 08.09.2015 21:43:27
скалогрыз
а почему на двоичное представление строки, все сразу же рекомендуют Hex?

может это школьно-студенческое задание?
Код: Выделить всё
{$mode delphi}
var
s : string;
i : integer;
begin
readln(s);
for i:=1 to length(s) do
writeln(BinStr( byte(s[i]), 8 ));
end.
или более гламурный вариант
Код: Выделить всё
{$mode delphi}
var
s : string;
i : integer;
begin
readln(s);
for i:=1 to length(s) do
writeln(s[i],': ',BinStr( byte(s[i]), 8 ),' ',hexstr(byte(s[i]), 2));
end.
ShortString-и полезны там, где нет кучи (heap) или не желательно её использование, для всяких там embedded устройств, драйверов и других загрузчиков. Ибо располагаются в стеке.
Re: Двоичное представление строки
Добавлено: 09.09.2015 01:55:07
Pasha-V
Пасиб.

Re: Двоичное представление строки
Добавлено: 09.09.2015 06:39:51
скалогрыз
Pasha-V писал(а):Пасиб.

Если это задача для учебного заведения. То программка выше не прокатит. Всё что от тебя хотят это вложенный цикл с ord, and и shl или shr - по вкусу. Хотя можно простым mod 2 обойтись!
Так что препод может остаться недоволен binstr()
Re: Двоичное представление строки
Добавлено: 10.09.2015 01:24:19
bormant
скалогрыз,
Потому как экономнее, чем олдскульный oct. 2 против 3, или 3 против 4 с учетом пробелов разделителей.
Но не 2 против 8, как в byte to bin.
Re: Двоичное представление строки
Добавлено: 10.09.2015 06:56:03
Pasha-V
Нет, это не для учебы. Я уже давно выучился.

Просто хотел проверить, что происходит в памяти при операции Str := ''; Оказалось, что просто нулевой байт обнуляется, а остальные не меняются.
Добавлено спустя 23 минуты 23 секунды:А до этого предполагал, что вся строка обнуляется.
