bdiv.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. { %OPT=-O2 }
  2. program bdiv;
  3. {$mode objfpc}{$H+}
  4. uses
  5. SysUtils;
  6. { Utility functions }
  7. function GetRealTime(const st: TSystemTime): Real;
  8. begin
  9. Result := st.Hour*3600.0 + st.Minute*60.0 + st.Second + st.MilliSecond/1000.0;
  10. end;
  11. {$push}
  12. {$warn 5057 off}
  13. function GetRealTime : Real;
  14. var
  15. st:TSystemTime;
  16. begin
  17. GetLocalTime(st);
  18. result:=GetRealTime(st);
  19. end;
  20. {$pop}
  21. const
  22. ITERATIONS = 524288;
  23. INTERNAL_LOOPS = 64;
  24. { TTestAncestor }
  25. type
  26. TTestAncestor = class
  27. private
  28. FStartTime: Real;
  29. FEndTime: Real;
  30. FAvgTime: Real;
  31. procedure SetStartTime;
  32. procedure SetEndTime;
  33. protected
  34. procedure DoTestIteration(Iteration: Integer); virtual; abstract;
  35. public
  36. constructor Create; virtual;
  37. destructor Destroy; override;
  38. procedure Run;
  39. function TestTitle: shortstring; virtual; abstract;
  40. function WriteResults: Boolean; virtual; abstract;
  41. property RunTime: Real read FAvgTime;
  42. end;
  43. TTestClass = class of TTestAncestor;
  44. TUInt16DivTest = class(TTestAncestor)
  45. protected
  46. FInputArray: array[$00..$FF] of Word;
  47. FResultArray: array[$00..$FF] of Word;
  48. function GetDivisor: Word; virtual; abstract;
  49. function DoVariableDiv(Numerator: Word): Word; inline;
  50. public
  51. function WriteResults: Boolean; override;
  52. end;
  53. TUInt16ModTest = class(TUInt16DivTest)
  54. protected
  55. function DoVariableMod(Numerator: Word): Word; inline;
  56. public
  57. function WriteResults: Boolean; override;
  58. end;
  59. TUInt32DivTest = class(TTestAncestor)
  60. protected
  61. FInputArray: array[$00..$FF] of Cardinal;
  62. FResultArray: array[$00..$FF] of Cardinal;
  63. function GetDivisor: Cardinal; virtual; abstract;
  64. function DoVariableDiv(Numerator: Cardinal): Cardinal; inline;
  65. public
  66. function WriteResults: Boolean; override;
  67. end;
  68. TUInt32ModTest = class(TUInt32DivTest)
  69. protected
  70. function DoVariableMod(Numerator: Cardinal): Cardinal; inline;
  71. public
  72. function WriteResults: Boolean; override;
  73. end;
  74. TSInt32DivTest = class(TTestAncestor)
  75. protected
  76. FInputArray: array[$00..$FF] of Integer;
  77. FResultArray: array[$00..$FF] of Integer;
  78. function GetDivisor: Integer; virtual; abstract;
  79. function DoVariableDiv(Numerator: Integer): Integer; inline;
  80. public
  81. function WriteResults: Boolean; override;
  82. end;
  83. TSInt32ModTest = class(TSInt32DivTest)
  84. protected
  85. function DoVariableMod(Numerator: Integer): Integer; inline;
  86. public
  87. function WriteResults: Boolean; override;
  88. end;
  89. TUInt64DivTest = class(TTestAncestor)
  90. protected
  91. FInputArray: array[$00..$FF] of QWord;
  92. FResultArray: array[$00..$FF] of QWord;
  93. function GetDivisor: QWord; virtual; abstract;
  94. function DoVariableDiv(Numerator: QWord): QWord; inline;
  95. public
  96. function WriteResults: Boolean; override;
  97. end;
  98. TUInt64ModTest = class(TUInt64DivTest)
  99. protected
  100. function DoVariableMod(Numerator: QWord): QWord; inline;
  101. public
  102. function WriteResults: Boolean; override;
  103. end;
  104. TSInt64DivTest = class(TTestAncestor)
  105. protected
  106. FInputArray: array[$00..$FF] of Int64;
  107. FResultArray: array[$00..$FF] of Int64;
  108. function GetDivisor: Int64; virtual; abstract;
  109. function DoVariableDiv(Numerator: Int64): Int64; inline;
  110. public
  111. function WriteResults: Boolean; override;
  112. end;
  113. TSInt64ModTest = class(TSInt64DivTest)
  114. protected
  115. function DoVariableMod(Numerator: Int64): Int64; inline;
  116. public
  117. function WriteResults: Boolean; override;
  118. end;
  119. TUInt32ModCmpTest = class(TTestAncestor)
  120. protected
  121. FInputArray: array[$00..$FF] of Cardinal;
  122. FResultArray: array[$00..$FF] of Boolean;
  123. function GetDivisor: Cardinal; virtual; abstract;
  124. function DoMod0(Numerator: Cardinal): Boolean; inline;
  125. public
  126. function WriteResults: Boolean; override;
  127. end;
  128. TSInt32ModCmpTest = class(TTestAncestor)
  129. protected
  130. FInputArray: array[$00..$FF] of Integer;
  131. FResultArray: array[$00..$FF] of Boolean;
  132. function GetDivisor: Integer; virtual; abstract;
  133. function DoMod0(Numerator: Integer): Boolean; inline;
  134. public
  135. function WriteResults: Boolean; override;
  136. end;
  137. TUInt64ModCmpTest = class(TTestAncestor)
  138. protected
  139. FInputArray: array[$00..$FF] of QWord;
  140. FResultArray: array[$00..$FF] of Boolean;
  141. function GetDivisor: QWord; virtual; abstract;
  142. function DoMod0(Numerator: QWord): Boolean; inline;
  143. public
  144. function WriteResults: Boolean; override;
  145. end;
  146. TSInt64ModCmpTest = class(TTestAncestor)
  147. protected
  148. FInputArray: array[$00..$FF] of Int64;
  149. FResultArray: array[$00..$FF] of Boolean;
  150. function GetDivisor: Int64; virtual; abstract;
  151. function DoMod0(Numerator: Int64): Boolean; inline;
  152. public
  153. function WriteResults: Boolean; override;
  154. end;
  155. {$I bdiv_u16.inc}
  156. {$I bdiv_u32.inc}
  157. {$I bdiv_u64.inc}
  158. {$I bdiv_s32.inc}
  159. {$I bdiv_s64.inc}
  160. { TTestAncestor }
  161. constructor TTestAncestor.Create;
  162. begin
  163. FStartTime := 0;
  164. FEndTime := 0;
  165. FAvgTime := 0;
  166. end;
  167. destructor TTestAncestor.Destroy;
  168. begin
  169. inherited Destroy;
  170. end;
  171. procedure TTestAncestor.SetStartTime;
  172. begin
  173. FStartTime := GetRealTime();
  174. end;
  175. procedure TTestAncestor.SetEndTime;
  176. begin
  177. FEndTime := GetRealTime();
  178. if FEndTime < FStartTime then { Happens if the test runs past midnight }
  179. FEndTime := FEndTime + 86400.0;
  180. end;
  181. procedure TTestAncestor.Run;
  182. var
  183. X: Integer;
  184. begin
  185. SetStartTime;
  186. for X := 0 to ITERATIONS - 1 do
  187. DoTestIteration(X);
  188. SetEndTime;
  189. FAvgTime := FEndTime - FStartTime;
  190. end;
  191. { TUInt16DivTest }
  192. function TUInt16DivTest.DoVariableDiv(Numerator: Word): Word;
  193. begin
  194. Result := Numerator div GetDivisor;
  195. end;
  196. function TUInt16DivTest.WriteResults: Boolean;
  197. var
  198. X: Integer;
  199. Expected: Word;
  200. begin
  201. Result := True;
  202. for X := 0 to 255 do
  203. begin
  204. Expected := DoVariableDiv(FInputArray[X]);
  205. if FResultArray[X] <> Expected then
  206. begin
  207. WriteLn('FAIL - ', FInputArray[X], ' div ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  208. Result := False;
  209. Exit;
  210. end;
  211. end;
  212. end;
  213. { TUInt16ModTest }
  214. function TUInt16ModTest.DoVariableMod(Numerator: Word): Word;
  215. begin
  216. Result := Numerator mod GetDivisor;
  217. end;
  218. function TUInt16ModTest.WriteResults: Boolean;
  219. var
  220. X: Integer;
  221. Expected: Word;
  222. begin
  223. Result := True;
  224. for X := 0 to 255 do
  225. begin
  226. Expected := DoVariableMod(FInputArray[X]);
  227. if FResultArray[X] <> Expected then
  228. begin
  229. WriteLn('FAIL - ', FInputArray[X], ' mod ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  230. Result := False;
  231. Exit;
  232. end;
  233. end;
  234. end;
  235. { TUInt32DivTest }
  236. function TUInt32DivTest.DoVariableDiv(Numerator: Cardinal): Cardinal;
  237. begin
  238. Result := Numerator div GetDivisor;
  239. end;
  240. function TUInt32DivTest.WriteResults: Boolean;
  241. var
  242. X: Integer;
  243. Expected: Cardinal;
  244. begin
  245. Result := True;
  246. for X := 0 to 255 do
  247. begin
  248. Expected := DoVariableDiv(FInputArray[X]);
  249. if FResultArray[X] <> Expected then
  250. begin
  251. WriteLn('FAIL - ', FInputArray[X], ' div ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  252. Result := False;
  253. Exit;
  254. end;
  255. end;
  256. end;
  257. { TUInt32ModTest }
  258. function TUInt32ModTest.DoVariableMod(Numerator: Cardinal): Cardinal;
  259. begin
  260. Result := Numerator mod GetDivisor;
  261. end;
  262. function TUInt32ModTest.WriteResults: Boolean;
  263. var
  264. X: Integer;
  265. Expected: Cardinal;
  266. begin
  267. Result := True;
  268. for X := 0 to 255 do
  269. begin
  270. Expected := DoVariableMod(FInputArray[X]);
  271. if FResultArray[X] <> Expected then
  272. begin
  273. WriteLn('FAIL - ', FInputArray[X], ' mod ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  274. Result := False;
  275. Exit;
  276. end;
  277. end;
  278. end;
  279. { TSInt32DivTest }
  280. function TSInt32DivTest.DoVariableDiv(Numerator: Integer): Integer;
  281. begin
  282. Result := Numerator div GetDivisor;
  283. end;
  284. function TSInt32DivTest.WriteResults: Boolean;
  285. var
  286. X: Integer;
  287. Expected: Integer;
  288. begin
  289. Result := True;
  290. for X := 0 to 255 do
  291. begin
  292. Expected := DoVariableDiv(FInputArray[X]);
  293. if FResultArray[X] <> Expected then
  294. begin
  295. WriteLn('FAIL - ', FInputArray[X], ' div ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  296. Result := False;
  297. Exit;
  298. end;
  299. end;
  300. end;
  301. { TSInt32ModTest }
  302. function TSInt32ModTest.DoVariableMod(Numerator: Integer): Integer;
  303. begin
  304. Result := Numerator mod GetDivisor;
  305. end;
  306. function TSInt32ModTest.WriteResults: Boolean;
  307. var
  308. X: Integer;
  309. Expected: Integer;
  310. begin
  311. Result := True;
  312. for X := 0 to 255 do
  313. begin
  314. Expected := DoVariableMod(FInputArray[X]);
  315. if FResultArray[X] <> Expected then
  316. begin
  317. WriteLn('FAIL - ', FInputArray[X], ' mod ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  318. Result := False;
  319. Exit;
  320. end;
  321. end;
  322. end;
  323. { TUInt64DivTest }
  324. function TUInt64DivTest.DoVariableDiv(Numerator: QWord): QWord;
  325. begin
  326. Result := Numerator div GetDivisor;
  327. end;
  328. function TUInt64DivTest.WriteResults: Boolean;
  329. var
  330. X: Integer;
  331. Expected: QWord;
  332. begin
  333. Result := True;
  334. for X := 0 to 255 do
  335. begin
  336. Expected := DoVariableDiv(FInputArray[X]);
  337. if FResultArray[X] <> Expected then
  338. begin
  339. WriteLn('FAIL - ', FInputArray[X], ' div ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  340. Result := False;
  341. Exit;
  342. end;
  343. end;
  344. end;
  345. { TUInt64ModTest }
  346. function TUInt64ModTest.DoVariableMod(Numerator: QWord): QWord;
  347. begin
  348. Result := Numerator mod GetDivisor;
  349. end;
  350. function TUInt64ModTest.WriteResults: Boolean;
  351. var
  352. X: Integer;
  353. Expected: QWord;
  354. begin
  355. Result := True;
  356. for X := 0 to 255 do
  357. begin
  358. Expected := DoVariableMod(FInputArray[X]);
  359. if FResultArray[X] <> Expected then
  360. begin
  361. WriteLn('FAIL - ', FInputArray[X], ' mod ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  362. Result := False;
  363. Exit;
  364. end;
  365. end;
  366. end;
  367. { TSInt64DivTest }
  368. function TSInt64DivTest.DoVariableDiv(Numerator: Int64): Int64;
  369. begin
  370. Result := Numerator div GetDivisor;
  371. end;
  372. function TSInt64DivTest.WriteResults: Boolean;
  373. var
  374. X: Integer;
  375. Expected: Int64;
  376. begin
  377. Result := True;
  378. for X := 0 to 255 do
  379. begin
  380. Expected := DoVariableDiv(FInputArray[X]);
  381. if FResultArray[X] <> Expected then
  382. begin
  383. WriteLn('FAIL - ', FInputArray[X], ' div ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  384. Result := False;
  385. Exit;
  386. end;
  387. end;
  388. end;
  389. { TSInt64ModTest }
  390. function TSInt64ModTest.DoVariableMod(Numerator: Int64): Int64;
  391. begin
  392. Result := Numerator mod GetDivisor;
  393. end;
  394. function TSInt64ModTest.WriteResults: Boolean;
  395. var
  396. X: Integer;
  397. Expected: Int64;
  398. begin
  399. Result := True;
  400. for X := 0 to 255 do
  401. begin
  402. Expected := DoVariableMod(FInputArray[X]);
  403. if FResultArray[X] <> Expected then
  404. begin
  405. WriteLn('FAIL - ', FInputArray[X], ' mod ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
  406. Result := False;
  407. Exit;
  408. end;
  409. end;
  410. end;
  411. { TSInt32ModCmpTest }
  412. function TSInt32ModCmpTest.DoMod0(Numerator: Integer): Boolean;
  413. begin
  414. Result := (Numerator mod GetDivisor) = 0;
  415. end;
  416. function TSInt32ModCmpTest.WriteResults: Boolean;
  417. var
  418. X: Integer;
  419. Expected: Boolean;
  420. begin
  421. Result := True;
  422. for X := 0 to 255 do
  423. begin
  424. Expected := DoMod0(FInputArray[X]);
  425. if FResultArray[X] <> Expected then
  426. begin
  427. WriteLn('FAIL - (', FInputArray[X], ' mod ', GetDivisor, ') = 0; expected ', Expected, ' got ', FResultArray[X]);
  428. Result := False;
  429. Exit;
  430. end;
  431. end;
  432. end;
  433. { TUInt32ModCmpTest }
  434. function TUInt32ModCmpTest.DoMod0(Numerator: Cardinal): Boolean;
  435. begin
  436. Result := (Numerator mod GetDivisor) = 0;
  437. end;
  438. function TUInt32ModCmpTest.WriteResults: Boolean;
  439. var
  440. X: Integer;
  441. Expected: Boolean;
  442. begin
  443. Result := True;
  444. for X := 0 to 255 do
  445. begin
  446. Expected := DoMod0(FInputArray[X]);
  447. if FResultArray[X] <> Expected then
  448. begin
  449. WriteLn('FAIL - (', FInputArray[X], ' mod ', GetDivisor, ') = 0; expected ', Expected, ' got ', FResultArray[X]);
  450. Result := False;
  451. Exit;
  452. end;
  453. end;
  454. end;
  455. { TSInt64ModCmpTest }
  456. function TSInt64ModCmpTest.DoMod0(Numerator: Int64): Boolean;
  457. begin
  458. Result := (Numerator mod GetDivisor) = 0;
  459. end;
  460. function TSInt64ModCmpTest.WriteResults: Boolean;
  461. var
  462. X: Integer;
  463. Expected: Boolean;
  464. begin
  465. Result := True;
  466. for X := 0 to 255 do
  467. begin
  468. Expected := DoMod0(FInputArray[X]);
  469. if FResultArray[X] <> Expected then
  470. begin
  471. WriteLn('FAIL - (', FInputArray[X], ' mod ', GetDivisor, ') = 0; expected ', Expected, ' got ', FResultArray[X]);
  472. Result := False;
  473. Exit;
  474. end;
  475. end;
  476. end;
  477. { TUInt64ModCmpTest }
  478. function TUInt64ModCmpTest.DoMod0(Numerator: QWord): Boolean;
  479. begin
  480. Result := (Numerator mod GetDivisor) = 0;
  481. end;
  482. function TUInt64ModCmpTest.WriteResults: Boolean;
  483. var
  484. X: Integer;
  485. Expected: Boolean;
  486. begin
  487. Result := True;
  488. for X := 0 to 255 do
  489. begin
  490. Expected := DoMod0(FInputArray[X]);
  491. if FResultArray[X] <> Expected then
  492. begin
  493. WriteLn('FAIL - (', FInputArray[X], ' mod ', GetDivisor, ') = 0; expected ', Expected, ' got ', FResultArray[X]);
  494. Result := False;
  495. Exit;
  496. end;
  497. end;
  498. end;
  499. { Main function }
  500. const
  501. TestClasses: array[0..84] of TTestClass = (
  502. TUInt16Bit1Test,
  503. TUInt16Bit1ModTest,
  504. TUInt16Bit2Test,
  505. TUInt16Bit2ModTest,
  506. TUInt16Bit3Test,
  507. TUInt16Bit3ModTest,
  508. TUInt16Bit7Test,
  509. TUInt16Bit7ModTest,
  510. TUInt16Bit10Test,
  511. TUInt16Bit10ModTest,
  512. TUInt16Bit100Test,
  513. TUInt16Bit100ModTest,
  514. TUInt16Bit1000Test,
  515. TUInt16Bit1000ModTest,
  516. TUInt32Bit1Test,
  517. TUInt32Bit1ModTest,
  518. TUInt32Bit2Test,
  519. TUInt32Bit2ModTest,
  520. TUInt32Bit3Test,
  521. TUInt32Bit3ModTest,
  522. TUInt32Bit7Test,
  523. TUInt32Bit7ModTest,
  524. TUInt32Bit10Test,
  525. TUInt32Bit10ModTest,
  526. TUInt32Bit100Test,
  527. TUInt32Bit100ModTest,
  528. TUInt32Bit1000Test,
  529. TUInt32Bit1000ModTest,
  530. TUInt32Bit60000Test,
  531. TUInt32Bit60000ModTest,
  532. TUInt32Bit146097Test,
  533. TUInt32Bit146097ModTest,
  534. TUInt32Bit3600000Test,
  535. TUInt32Bit3600000ModTest,
  536. TUInt64Bit1Test,
  537. TUInt64Bit1ModTest,
  538. TUInt64Bit2Test,
  539. TUInt64Bit2ModTest,
  540. TUInt64Bit3Test,
  541. TUInt64Bit3ModTest,
  542. TUInt64Bit7Test,
  543. TUInt64Bit7ModTest,
  544. TUInt64Bit10Test,
  545. TUInt64Bit10ModTest,
  546. TUInt64Bit100Test,
  547. TUInt64Bit100ModTest,
  548. TUInt64Bit1000000000Test,
  549. TUInt64Bit1000000000ModTest,
  550. TSInt32Bit1Test,
  551. TSInt32Bit1ModTest,
  552. TSInt32Bit100Test,
  553. TSInt32Bit100ModTest,
  554. TSInt64Bit1Test,
  555. TSInt64Bit1ModTest,
  556. TSInt64Bit10Test,
  557. TSInt64Bit10ModTest,
  558. TSInt64Bit18Test,
  559. TSInt64Bit18ModTest,
  560. TSInt64Bit24Test,
  561. TSInt64Bit24ModTest,
  562. TSInt64Bit100Test,
  563. TSInt64Bit100ModTest,
  564. TSInt64Bit153Test,
  565. TSInt64Bit153ModTest,
  566. TSInt64Bit1461Test,
  567. TSInt64Bit1461ModTest,
  568. TSInt64Bit10000Test,
  569. TSInt64Bit10000ModTest,
  570. TSInt64Bit86400000Test,
  571. TSInt64Bit86400000ModTest,
  572. TUInt32Bit3ModCmpTest,
  573. TSInt32Bit3ModCmpTest,
  574. TUInt32Bit10ModCmpTest,
  575. TSInt32Bit10ModCmpTest,
  576. TUInt32Bit100ModCmpTest,
  577. TSInt32Bit100ModCmpTest,
  578. TUInt32Bit400ModCmpTest,
  579. TUInt32Bit1000ModCmpTest,
  580. TUInt64Bit3ModCmpTest,
  581. TSInt64Bit3ModCmpTest,
  582. TUInt64Bit10ModCmpTest,
  583. TSInt64Bit10000ModCmpTest,
  584. TUInt64Bit100ModCmpTest,
  585. TSInt64Bit86400000ModCmpTest,
  586. TUInt64Bit1000000000ModCmpTest
  587. );
  588. var
  589. CurrentObject: TTestAncestor;
  590. Failed: Boolean;
  591. X: Integer;
  592. SummedUpAverageDuration, AverageDuration : Double;
  593. begin
  594. SummedUpAverageDuration := 0.0;
  595. Failed := False;
  596. WriteLn('Division compilation and timing test (using constants from System and Sysutils)');
  597. WriteLn('-------------------------------------------------------------------------------');
  598. for X := Low(TestClasses) to High(TestClasses) do
  599. begin
  600. try
  601. CurrentObject := TestClasses[X].Create;
  602. try
  603. Write(CurrentObject.TestTitle:43, ' - ');
  604. CurrentObject.Run;
  605. if CurrentObject.WriteResults then
  606. begin
  607. AverageDuration := ((CurrentObject.RunTime * 1000000000.0) / (ITERATIONS * INTERNAL_LOOPS));
  608. WriteLn('Pass - average iteration duration: ', AverageDuration:1:3, ' ns');
  609. SummedUpAverageDuration := SummedUpAverageDuration + AverageDuration;
  610. end
  611. else
  612. { Final average isn't processed if a test failed, so there's no need
  613. to calculate and add the average duration to it }
  614. Failed := True;
  615. finally
  616. CurrentObject.Free;
  617. end;
  618. except on E: Exception do
  619. begin
  620. WriteLn('Exception "', E.ClassName, '" raised while running test object of class "', TestClasses[X].ClassName, '"');
  621. Failed := True;
  622. end;
  623. end;
  624. end;
  625. if Failed then
  626. Halt(1);
  627. WriteLn(#10'ok');
  628. WriteLn('- Sum of average durations: ', SummedUpAverageDuration:1:3, ' ns');
  629. WriteLn('- Overall average duration: ', (SummedUpAverageDuration / Length(TestClasses)):1:3, ' ns');
  630. end.