ОК, ребята, вот полный код, который поможет мне справиться с этой проблемой:
function Unescape(const s: AnsiString): string;
var
i: Integer;
j: Integer;
c: Integer;
begin
// Make result at least large enough. This prevents too many reallocs
SetLength(Result, Length(s));
i := 1;
j := 1;
while i <= Length(s) do begin
if s[i] = '\' then begin
if i < Length(s) then begin
// escaped backslash?
if s[i + 1] = '\' then begin
Result[j] := '\';
inc(i, 2);
end
// convert hex number to WideChar
else if (s[i + 1] = 'u') and (i + 1 + 4 <= Length(s))
and TryStrToInt('$' + string(Copy(s, i + 2, 4)), c) then begin
inc(i, 6);
Result[j] := WideChar(c);
end else begin
raise Exception.CreateFmt('Invalid code at position %d', [i]);
end;
end else begin
raise Exception.Create('Unexpected end of string');
end;
end else begin
Result[j] := WideChar(s[i]);
inc(i);
end;
inc(j);
end;
// Trim result in case we reserved too much space
SetLength(Result, j - 1);
end;
const
NormalizationC = 1;
function NormalizeString(NormForm: Integer; lpSrcString: PWideChar; cwSrcLength: Integer;
lpDstString: PWideChar; cwDstLength: Integer): Integer; stdcall; external 'Normaliz.dll';
function Normalize(const s: string): string;
var
newLength: integer;
begin
// in NormalizationC mode the result string won't grow longer than the input string
SetLength(Result, Length(s));
newLength := NormalizeString(NormalizationC, PChar(s), Length(s), PChar(Result), Length(Result));
SetLength(Result, newLength);
end;
function UnescapeAndNormalize(const s: AnsiString): string;
begin
Result := Normalize(Unescape(s));
end;
Код украден из этого ответа
Моя внутренняя реакция заключалась в том, что объем памяти для Date будет очень маленьким. Изучая исходный код, кажется, что класс содержит только одно поле экземпляра (долгое время называется миллисекундами). Это означает, что размер объекта даты равен размеру long плюс размер экземпляра Object, то есть очень мал.
Затем я нашел этот код , который создает тысячи объектов для определения размера объекта. Это говорит о том, что размер java.util.Date
составляет 32 байта. Сравните это с простым хранением даты как long (что она и делает внутри) - long - 8 байт, поэтому вам нужно заплатить в четыре раза для удобства наличия объекта date.
Тем не менее, накладные расходы на создание объектов не очень высоки. Так что если вы действительно беспокоитесь о пространстве, сохраните даты как длинные и создайте объект Date по мере необходимости.
Как ответили и здесь : sup>
Самый простой способ ответить на этот вопрос - взглянуть на исходный код java.util.Date
.
Он имеет только 2 нестатических поля (Java 1.7.0_55):
private transient long fastTime;
private transient BaseCalendar.Date cdate;
long
имеет объем памяти 8 байтов, а cdate
является ссылкой на объект, который имеет размер 4 байта. Таким образом, в общей сложности 12 байтов .
Если бы был создан экземпляр cdate
, это могло бы потребовать дополнительных байтов в памяти, но если вы посмотрите и на конструкторы, иногда это даже не будет затронуто, а в других оно будет null
-обработано в конец конструктора, поэтому конечный результат также составляет 12 байт .
Это только для создания Date
. Если вы вызываете методы для Date
(например, Date.toString()
), то будет создавать и сохранять объект в поле cdate
, которое не будет очищено. Поэтому, если вы вызовете определенные методы для Date
, его использование памяти увеличится.
Примечание: Ссылки на объекты могут иметь длину 64 бита на 64-битных JVM, в этом случае использование памяти будет составлять 16 байтов.
Примечание № 2: Также обратите внимание, что это только использование памяти самого объекта Date
. Скорее всего, вы будете хранить его ссылку где-нибудь, например. в массиве или списке или поле в каком-либо другом классе, для которого потребуются дополнительные 4 байта (или, может быть, 8 байтов на 64-битных JVM).