View Issue Details

IDProjectCategoryView StatusLast Update
0038756FPCCompilerpublic2021-04-14 19:24
Reporterrunewalsh Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Product Version3.3.1 
Summary0038756: Inefficient comparison between string and char array
DescriptionThe code attached generates 18 calls to fpc_CharArray_To_AnsiStr. Could it get along without a single one? :(

To be fair, it ends up with only one allocation (still 18 calls, but seeminly reusing the same allocation) when all of these comparisons are in one scope.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Activities

runewalsh

2021-04-14 19:24

reporter  

magic_chars.pas (2,725 bytes)   
{$mode objfpc} {$h+}
{$warn 5037 off} {$warn 5058 off}

type
	MagicChars = array[0 .. 3] of char;

var
	oldMM, newMM: TMemoryManager;
	nAllocs: uint32;

	function GetMemOverride(size: PtrUint): pointer;
	begin
		nAllocs += 1;
		result := oldMM.GetMem(size);
	end;

	function IsIHDR(const m: MagicChars): boolean; begin result := m = 'IHDR'; end;
	function IscHRM(const m: MagicChars): boolean; begin result := m = 'cHRM'; end;
	function IsgAMA(const m: MagicChars): boolean; begin result := m = 'gAMA'; end;
	function IsiCCP(const m: MagicChars): boolean; begin result := m = 'iCCP'; end;
	function IssBIT(const m: MagicChars): boolean; begin result := m = 'sBIT'; end;
	function IssRGB(const m: MagicChars): boolean; begin result := m = 'sRGB'; end;
	function IsPLTE(const m: MagicChars): boolean; begin result := m = 'PLTE'; end;
	function IsbKGD(const m: MagicChars): boolean; begin result := m = 'bKGD'; end;
	function IshIST(const m: MagicChars): boolean; begin result := m = 'hIST'; end;
	function IstRNS(const m: MagicChars): boolean; begin result := m = 'tRNS'; end;
	function IspHYs(const m: MagicChars): boolean; begin result := m = 'pHYs'; end;
	function IssPLT(const m: MagicChars): boolean; begin result := m = 'sPLT'; end;
	function IstIME(const m: MagicChars): boolean; begin result := m = 'tIME'; end;
	function IsiTXt(const m: MagicChars): boolean; begin result := m = 'iTXt'; end;
	function IstEXt(const m: MagicChars): boolean; begin result := m = 'tEXt'; end;
	function IszTXt(const m: MagicChars): boolean; begin result := m = 'zTXt'; end;
	function IsIDAT(const m: MagicChars): boolean; begin result := m = 'IDAT'; end;
	function IsIEND(const m: MagicChars): boolean; begin result := m = 'IEND'; end;

var
	m: MagicChars;

begin
	GetMemoryManager(oldMM);
	newMM := oldMM;
	newMM.GetMem := @GetMemOverride;
	SetMemoryManager(newMM);

	try
		m := 'UNKN';
		if IsIHDR(m) then writeln('IHDR')
		else if IscHRM(m) then writeln('cHRM')
		else if IsgAMA(m) then writeln('gAMA')
		else if IsiCCP(m) then writeln('iCCP')
		else if IssBIT(m) then writeln('sBIT')
		else if IssRGB(m) then writeln('sRGB')
		else if IsPLTE(m) then writeln('PLTE')
		else if IsbKGD(m) then writeln('bKGD')
		else if IshIST(m) then writeln('hIST')
		else if IstRNS(m) then writeln('tRNS')
		else if IspHYs(m) then writeln('pHYs')
		else if IssPLT(m) then writeln('sPLT')
		else if IstIME(m) then writeln('tIME')
		else if IsiTXt(m) then writeln('iTXt')
		else if IstEXt(m) then writeln('tEXt')
		else if IszTXt(m) then writeln('zTXt')
		else if IsIDAT(m) then writeln('IDAT')
		else if IsIEND(m) then writeln('IEND')
		else writeln('(unknown)');

		writeln('Allocations: ', nAllocs);
	finally
		SetMemoryManager(OldMM);
	end;
end.
magic_chars.pas (2,725 bytes)   

Issue History

Date Modified Username Field Change
2021-04-14 19:24 runewalsh New Issue
2021-04-14 19:24 runewalsh File Added: magic_chars.pas