본문 바로가기

delphi575

TParallel.For로 루프 병렬화하여 멀티코어 성능 끌어올리기 (Advanced) TParallel.For로 루프 병렬화하여 멀티코어 성능 끌어올리기 (Advanced) CPU 연산이 많은 루프를 그대로 돌리면 코어가 여러 개 있어도 한 코어만 쓰는 경우가 많습니다. System.Threading의 TParallel.For를 사용하면 동일한 루프를 자동으로 작업 분할해 여러 코어에서 동시에 처리하므로 실행 시간이 크게 단축될 수 있습니다. uses System.SysUtils, System.Threading, System.SyncObjs, System.Diagnostics; procedure ParallelSumDemo; const N = 5_000_000; var Data: TArray; I: Integer; Total: Int64; SW: TStopwa.. 2025. 9. 11.
Record Helpers로 코드 가독성 높이기 (Intermediate) Record Helpers로 코드 가독성 높이기 (Intermediate) 델파이(Delphi)에서 record는 가벼운 데이터 구조체로 자주 사용됩니다. 하지만 기능이 제한적일 수 있습니다. record helper를 사용하면 기존 record에 메서드나 속성을 확장해 넣을 수 있어, 코드의 가독성과 재사용성을 크게 향상시킬 수 있습니다. uses System.SysUtils; type TPoint = record X, Y: Integer; end; // Record Helper 선언 TPointHelper = record helper for TPoint function ToString: string; function DistanceTo(const P: TP.. 2025. 9. 10.
TStringList 활용하기 (Intermediate) TStringList 활용하기 (Intermediate)델파이(Delphi)에서 텍스트 데이터를 다룰 때 가장 많이 쓰이는 클래스 중 하나가 TStringList입니다. 파일에서 문자열을 읽고 쓰거나, 키-값 쌍을 관리하거나, 정렬과 검색까지 간단하게 처리할 수 있습니다. uses System.SysUtils, System.Classes; procedure TestStringList; var SL: TStringList; begin SL := TStringList.Create; try // 문자열 추가 SL.Add('Apple'); SL.Add('Banana'); SL.Add('Cherry'); // 특정 인덱스 접근 Writeln('첫 번째.. 2025. 9. 9.
TFDQuery.FieldByName 성능 최적화하기 TFDQuery.FieldByName 성능 최적화하기반복 루프 안에서 FieldByName을 직접 호출하면 성능 저하가 발생할 수 있습니다. 필드 객체를 캐싱해두면 처리 속도를 크게 개선할 수 있습니다. procedure OptimizeFieldAccess(Qry: TFDQuery); var FName, FEmail: TField; begin Qry.SQL.Text := 'SELECT Name, Email FROM Customers'; Qry.Open; // 필드 캐싱 FName := Qry.FieldByName('Name'); FEmail := Qry.FieldByName('Email'); while not Qry.Eof do begin // 반복 루프에서 직접 .. 2025. 9. 8.
TMonitor를 이용한 객체 동기화 (Advanced) TMonitor를 이용한 객체 동기화 (Advanced)멀티스레드 환경에서 여러 스레드가 동일한 객체에 접근할 경우, 동기화가 필요합니다. TCriticalSection은 프로세스 내 자원 보호에 유용하지만, 델파이(Delphi)에서는 TMonitor라는 더 현대적이고 객체 지향적인 동기화 방법을 제공합니다. TMonitor는 객체 자체에 대한 잠금(lock)을 제공하며, Wait, Pulse, PulseAll을 통해 스레드 간 조건 동기화도 가능하게 합니다. uses System.SysUtils, System.Classes; type TSharedBuffer = class private FData: string; public procedure WriteData(.. 2025. 9. 5.
TCriticalSection으로 멀티스레드에서 자원 보호하기 (Intermediate) TCriticalSection으로 멀티스레드에서 자원 보호하기 (Intermediate)델파이(Delphi)에서 멀티스레드 프로그램을 작성할 때, 여러 스레드가 동시에 같은 변수나 객체를 수정하면 Race Condition(경쟁 상태) 이 발생할 수 있습니다. 이런 문제를 막으려면 스레드 간에 공유되는 자원 접근을 동기화해야 합니다. TCriticalSection은 간단하게 임계 구역(critical section)을 설정하여 한 번에 한 스레드만 진입하도록 보장합니다. uses System.Classes, System.SyncObjs, System.SysUtils; var Counter: Integer = 0; CS: TCriticalSection; procedure Incremen.. 2025. 9. 4.
TStringGrid에서 행 전체 복사/붙여넣기 기능 구현하기 TStringGrid에서 행 전체 복사/붙여넣기 기능 구현하기 업무용 그리드 화면에서 사용자가 행 전체를 복사/붙여넣기 할 수 있으면 데이터 입력 효율성이 크게 올라갑니다. uses Vcl.Clipbrd; procedure CopyRowToClipboard(Grid: TStringGrid; ARow: Integer); var Col: Integer; Line: string; begin Line := ''; for Col := 0 to Grid.ColCount - 1 do begin Line := Line + Grid.Cells[Col, ARow]; if Col Line := Line + #9; // 탭 구분자 end; Clipboard.AsText .. 2025. 9. 3.
루프에서 문자열 결합은 TStringBuilder로 최적화하기 (Intermediate) 루프에서 문자열 결합은 TStringBuilder로 최적화하기 (Intermediate)루프에서 S := S + ...로 문자열을 이어 붙이면 매번 새 버퍼가 생성되어 메모리 재할당과 복사가 반복됩니다. TStringBuilder는 내부 버퍼를 확장해가며 추가하기 때문에 할당/복사 횟수를 크게 줄여 대용량 처리에서 유리합니다. 초기 용량(Capacity)을 넉넉히 잡으면 더 빨라집니다. program StringBuilderDemo; {$APPTYPE CONSOLE} uses System.SysUtils, System.Diagnostics; function BuildWithPlus(Count: Integer): string; var i: Integer; S: string; begin .. 2025. 9. 3.
Const 매개변수로 성능 최적화하기 (Intermediate) Const 매개변수로 성능 최적화하기 (Intermediate) 델파이(Delphi)에서 큰 레코드나 긴 문자열을 함수에 전달할 때, 기본 매개변수는 값 복사가 일어나 성능이 떨어질 수 있습니다. 이때 const 키워드를 사용하면 참조 방식으로 전달되어 불필요한 복사가 줄어들고, 성능이 향상됩니다. type TLargeRecord = record Data: array[1..1000] of Integer; end; // 값 복사 방식 (비효율적일 수 있음) function ProcessData(Value: TLargeRecord): Integer; begin Result := Value.Data[1]; end; // const 매개변수 방식 (참조 전달, 성능 최적화) functio.. 2025. 9. 2.
FireDAC Array DML로 대량 INSERT를 수십 배 빠르게 처리하기 FireDAC Array DML로 대량 INSERT를 수십 배 빠르게 처리하기단일 INSERT 반복 대신 파라미터 배열을 한 번에 실행해 대량 데이터 적재 속도를 극적으로 끌어올립니다. uses System.SysUtils, System.Math, FireDAC.Comp.Client, FireDAC.Stan.Param; procedure BulkInsertOrders(AConn: TFDConnection); const N = 10000; // 전체 레코드 수 BATCH = 1000; // 배치 크기(커밋 간격) var Q: TFDQuery; i, fromIdx, toIdx: Integer; IDs: TArray; Customers: TArray; Amounts: T.. 2025. 9. 1.
TStopwatch 없이 QueryPerformanceCounter로 정밀 시간 측정 TStopwatch 없이 QueryPerformanceCounter로 정밀 시간 측정 uses Windows, SysUtils; procedure MeasurePerformance; var Freq, StartCount, EndCount: Int64; ElapsedMS: Double; begin QueryPerformanceFrequency(Freq); // CPU 타이머 주파수 QueryPerformanceCounter(StartCount); // 측정할 코드 블록 Sleep(123); QueryPerformanceCounter(EndCount); ElapsedMS := (EndCount - StartCount) * 1000 / Freq; Writeln(Format.. 2025. 8. 28.
Exit로 함수 흐름 단순화하기 (Beginner) Exit로 함수 흐름 단순화하기 (Beginner)델파이(Delphi)에서는 Exit 구문을 사용해 함수나 프로시저의 실행을 즉시 종료할 수 있습니다. 조건에 따라 빠르게 함수를 탈출하면 가독성이 좋아지고, 중첩된 if문을 줄일 수 있습니다. 단, 객체 해제 같은 정리 작업은 try..finally 블록 안에서 처리해야 합니다. function IsAdult(Age: Integer): Boolean; begin if Age Exit(False); // 잘못된 입력이면 바로 종료 if Age >= 18 then Exit(True); Result := False; // 그 외에는 False end; procedure TestExit; begin if IsAdult(20) .. 2025. 8. 27.
ApplicationEvents.OnException으로 전역 예외 처리하기 ApplicationEvents.OnException으로 전역 예외 처리하기프로그램 전반에서 발생하는 예외를 개별 try..except로 잡지 않고도, TApplicationEvents.OnException 이벤트를 사용하면 전역적으로 통합 처리할 수 있습니다. uses Vcl.AppEvnts, Vcl.Dialogs, System.SysUtils; procedure TForm1.FormCreate(Sender: TObject); begin ApplicationEvents1.OnException := AppExceptionHandler; end; procedure TForm1.AppExceptionHandler(Sender: TObject; E: Exception); begin // 예외 로.. 2025. 8. 26.
Delphi에서 제네릭 리스트(TList<T>) 효율적으로 사용하기 (Intermediate) Delphi에서 제네릭 리스트(TList) 효율적으로 사용하기 (Intermediate) 델파이(Delphi)에서 TList는 제네릭을 지원하는 강력한 리스트 컬렉션으로, 타입 안정성과 성능을 모두 제공합니다. 기존의 TList는 Pointer 기반이라 형변환이 필요했지만, TList는 컴파일 타임에 타입이 고정되어 안전합니다. 또한 for..in 구문과 함께 사용하면 더 직관적인 코드 작성이 가능합니다. uses System.Generics.Collections, System.SysUtils; procedure TestGenericList; var Numbers: TList; I: Integer; begin Numbers := TList.Create; try // 값 추가.. 2025. 8. 13.
FireDAC에서 매개변수화 쿼리로 SQL 인젝션 방지하기 (Intermediate) FireDAC에서 매개변수화 쿼리로 SQL 인젝션 방지하기 (Intermediate) Delphi에서 데이터베이스 쿼리를 실행할 때, 문자열을 직접 연결하면 SQL 인젝션 공격에 취약해질 수 있습니다. FireDAC의 TFDQuery 컴포넌트를 사용하면 매개변수화(Parameterized) 쿼리를 적용하여 보안성과 성능을 모두 향상시킬 수 있습니다. 매개변수는 :파라미터명 형식으로 선언하며, ParamByName 메서드로 값을 지정합니다. uses FireDAC.Comp.Client; procedure TForm1.btnSearchClick(Sender: TObject); begin FDQuery1.SQL.Text := 'SELECT * FROM Customers WHERE Name = :N.. 2025. 8. 12.
TPath.GetTempFileName + TFile로 안전한 임시 파일 사용하기 TPath.GetTempFileName + TFile로 안전한 임시 파일 사용하기임시 데이터를 다룰 때는 OS가 보장하는 임시 폴더와 충돌 없는 파일명을 쓰는 게 안전합니다. System.IOUtils의 TPath.GetTempPath, TPath.GetTempFileName과 TFile.WriteAllText/ReadAllText/Delete를 조합하면, 경로/이름 충돌 걱정 없이 생성→사용→정리까지 한 번에 처리할 수 있습니다. uses System.SysUtils, System.IOUtils; procedure UseTempFile; var TempDir, TempFile, Data, ReadBack: string; begin TempDir := TPath.GetTempPath;.. 2025. 8. 11.
TStringBuilder로 효율적인 문자열 결합하기 TStringBuilder로 효율적인 문자열 결합하기 Delphi에서 반복문이나 대량 문자열 조합 시 + 연산자를 사용하면 메모리 재할당이 빈번해 성능 저하가 발생할 수 있습니다. TStringBuilder는 내부 버퍼를 관리해 한 번만 메모리를 할당하고 문자열을 누적하므로, 대용량 텍스트 생성에 탁월합니다. uses System.SysUtils, System.Classes; procedure BuildLargeString; var SB: TStringBuilder; I: Integer; ResultStr: string; begin SB := TStringBuilder.Create; try for I := 1 to 10000 do SB.AppendFormat.. 2025. 8. 8.
TStreamReader로 인코딩된 텍스트 파일 읽기 (Beginner) TStreamReader로 인코딩된 텍스트 파일 읽기 (Beginner) 델파이에서 다양한 인코딩(UTF-8, ANSI 등)의 텍스트 파일을 읽을 때는 TStreamReader를 사용하면 간편합니다. TStreamReader 생성자에 인코딩을 지정해주면, 올바른 문자 변환이 자동으로 이뤄져 파일 내용이 깨지지 않습니다.​uses System.Classes, System.SysUtils;​procedure ReadTextFile(const FileName: string);var Reader: TStreamReader; Line: string;begin // UTF-8 인코딩으로 읽기 Reader := TStreamReader.Create(FileName, TEncoding.UTF8); try while n.. 2025. 8. 5.
TObjectList로 객체 메모리 자동 관리하기 TObjectList로 객체 메모리 자동 관리하기 델파이에서 객체 리스트를 다룰 때 수동으로 메모리를 해제하는 번거로움을 줄이기 위해 TObjectList를 사용하면 객체 소유권을 리스트가 가지게 되어 자동으로 메모리를 해제할 수 있습니다. uses System.Generics.Collections, System.SysUtils; type TCustomer = class Name: string; constructor Create(const AName: string); end; constructor TCustomer.Create(const AName: string); begin Name := AName; end; procedure TForm1.Button1Click(Send.. 2025. 7. 25.
TPath.ChangeExtension으로 파일 확장자 쉽게 변경하기 TPath.ChangeExtension으로 파일 확장자 쉽게 변경하기 파일의 확장자만 바꿔야 할 때, 문자열 조작 없이 TPath.ChangeExtension 함수를 사용하면 간편하고 안전하게 처리할 수 있습니다. 작업 파일 자동 이름 변경, 백업 파일 생성, 로그 리네이밍 등에 유용합니다. uses System.SysUtils, System.IOUtils; procedure ChangeFileExtDemo; var OldName, NewName: string; begin OldName := 'C:\Temp\report.txt'; NewName := TPath.ChangeExtension(OldName, '.bak'); ShowMessage('변경된 파일명: ' + NewName);.. 2025. 7. 21.