ansibench.pp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. program Bench2;
  2. {$APPTYPE CONSOLE}
  3. {$Mode Objfpc}
  4. {$H+}
  5. uses
  6. sysutils;
  7. const
  8. cTimes = 999999;
  9. Number1: array [0..19] of string = (
  10. 'zero', 'one', 'two', 'three', 'four', 'five',
  11. 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
  12. 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',
  13. 'seventeen', 'eighteen', 'nineteen');
  14. Number9: array [0..9] of string = (
  15. '', ' one', ' two', ' three', ' four', ' five',
  16. ' six', ' seven', ' eight', ' nine');
  17. Number10: array [0..9] of string = (
  18. 'zero', 'ten', 'twenty', 'thirty', 'fourty', 'fifty',
  19. 'sixty', 'seventy', 'eighty', 'ninety');
  20. function GetTickCount : Cardinal;
  21. var
  22. h,m,s,s1000 : word;
  23. begin
  24. decodetime(time,h,m,s,s1000);
  25. result:=h*3600000+m*60000+s*1000+s1000;
  26. end;
  27. var
  28. StartTick: Cardinal;
  29. procedure StartLog(const Text: string; Count: Integer);
  30. begin
  31. if Count > 0 then
  32. write(Text, ': ', Count, ' ... ')
  33. else
  34. write(Text, ' ... ');
  35. StartTick:= GetTickCount;
  36. end;
  37. procedure EndLog(const Text: string);
  38. begin
  39. writeln(Text, ' done in ', (GetTickCount - StartTick) / 1000.0: 0: 3, ' sec');
  40. end;
  41. type
  42. TFastStringRec = record
  43. l: Cardinal;
  44. s: string;
  45. end;
  46. procedure FS_Clear(var AFS: TFastStringRec); inline;
  47. begin
  48. AFS.L:= 0;
  49. AFS.S:= '';
  50. end;
  51. procedure FS_Assign(var AFS: TFastStringRec; const s: string); inline;
  52. begin
  53. AFS.l:= Length(s);
  54. SetLength(AFS.s, (AFS.l and not 63) + 64);
  55. if AFS.l > 0 then
  56. Move(s[1], AFS.s[1], AFS.l);
  57. end;
  58. procedure FS_Append(var AFS: TFastStringRec; const s: string); overload;
  59. inline;
  60. var
  61. L, ls: Cardinal;
  62. begin
  63. ls:= Length(s);
  64. if ls > 0 then begin
  65. L:= AFS.l;
  66. AFS.l:= L + ls;
  67. SetLength(AFS.s, (AFS.l and not 63) + 64);
  68. Move(s[1], AFS.s[1 + L], ls);
  69. end;
  70. end;
  71. procedure FS_Append(var AFS, S: TFastStringRec); overload; inline;
  72. var
  73. L: Cardinal;
  74. begin
  75. if S.L > 0 then begin
  76. L:= AFS.l;
  77. AFS.l:= L + S.L;
  78. SetLength(AFS.s, (AFS.l and not 63) + 64);
  79. Move(S.S[1], AFS.S[1 + L], S.L);
  80. end;
  81. end;
  82. function FS_ToStr(var AFS: TFastStringRec): string; inline;
  83. begin
  84. if AFS.L > 0 then begin
  85. SetLength(Result, AFS.L);
  86. Move(AFS.S[1], Result[1], AFS.L);
  87. end else
  88. Result:= '';
  89. end;
  90. procedure NumberToText_V1(out s: string; n: Integer);
  91. procedure TensToText(var s: TFastStringRec; dig: Integer);
  92. var
  93. x: Integer;
  94. begin
  95. if dig > 0 then begin
  96. if dig >= 20 then begin
  97. x:= dig mod 10;
  98. FS_Assign(s, Number10[dig div 10]);
  99. if x <> 0 then
  100. FS_Append(s, Number9[x]);
  101. end else begin
  102. FS_Assign(s, Number1[dig]);
  103. end;
  104. end else
  105. FS_Clear(s);
  106. end;
  107. procedure HundredsToText(var s: TFastStringRec; dig: Integer);
  108. var
  109. h, t: Integer;
  110. s1: TFastStringRec;
  111. begin
  112. if dig > 0 then begin
  113. t:= dig mod 100;
  114. h:= dig div 100;
  115. if h > 0 then begin
  116. TensToText(s, h);
  117. if t > 0 then begin
  118. FS_Append(s, ' houndred ');
  119. TensToText(s1, t);
  120. FS_Append(s, s1);
  121. end else
  122. FS_Append(s, ' houndred');
  123. end else
  124. TensToText(s, t);
  125. end else
  126. FS_Clear(s);
  127. end;
  128. var
  129. dig, h: Integer;
  130. s0, s1: TFastStringRec;
  131. begin
  132. if n > 0 then begin
  133. dig:= n div 1000;
  134. h:= n mod 1000;
  135. if dig > 0 then begin
  136. HundredsToText(s0, dig);
  137. if h > 0 then begin
  138. FS_Append(s0, ' thousand ');
  139. HundredsToText(s1, h);
  140. FS_Append(s0, s1);
  141. end else
  142. FS_Append(s0, ' thousand');
  143. end else
  144. HundredsToText(s0, h);
  145. s:= FS_ToStr(s0);
  146. end else
  147. s:= Number1[0];
  148. end;
  149. procedure NumberToText_V2(out s: string; n: Integer);
  150. procedure TensToText(out s: string; dig: Integer);
  151. var
  152. x: Integer;
  153. begin
  154. if dig > 0 then begin
  155. if dig >= 20 then begin
  156. x:= dig mod 10;
  157. if x <> 0 then begin
  158. s:= Number10[dig div 10] + Number9[x]
  159. end else
  160. s:= Number10[dig div 10];
  161. end else begin
  162. s:= Number1[dig];
  163. end;
  164. end else
  165. s:= '';
  166. end;
  167. procedure HundredsToText(out s: string; dig: Integer);
  168. var
  169. h, t: Integer;
  170. s1: string;
  171. begin
  172. if dig > 0 then begin
  173. t:= dig mod 100;
  174. h:= dig div 100;
  175. if h > 0 then begin
  176. TensToText(s, h);
  177. if t > 0 then begin
  178. s:= s + ' houndred ';
  179. TensToText(s1, t);
  180. s:= s + s1;
  181. end else
  182. s:= s + ' houndred';
  183. end else
  184. TensToText(s, t);
  185. end else
  186. s:= '';
  187. end;
  188. var
  189. dig, h: Integer;
  190. s1: string;
  191. begin
  192. if n > 0 then begin
  193. dig:= n div 1000;
  194. h:= n mod 1000;
  195. if dig > 0 then begin
  196. HundredsToText(s, dig);
  197. if h > 0 then begin
  198. s:= s + ' thousand ';
  199. HundredsToText(s1, h);
  200. s:= s + s1;
  201. end else
  202. s:= s + ' thousand';
  203. end else
  204. HundredsToText(s, h);
  205. end else
  206. s:= Number1[0];
  207. end;
  208. function NumberToText_V3(n: Integer): string;
  209. function TensToText(dig: Integer): string;
  210. var
  211. x: Integer;
  212. begin
  213. if dig > 0 then begin
  214. if dig >= 20 then begin
  215. x:= dig mod 10;
  216. if x <> 0 then begin
  217. Result:= Number10[dig div 10] + Number9[x]
  218. end else
  219. Result:= Number10[dig div 10];
  220. end else begin
  221. Result:= Number1[dig];
  222. end;
  223. end else
  224. Result:= '';
  225. end;
  226. function HundredsToText(dig: Integer): string;
  227. var
  228. h, t: Integer;
  229. begin
  230. if dig > 0 then begin
  231. t:= dig mod 100;
  232. h:= dig div 100;
  233. if h > 0 then begin
  234. if t > 0 then
  235. Result:= TensToText(h) + ' houndred ' + TensToText(t)
  236. else
  237. Result:= TensToText(h) + ' houndred';
  238. end else
  239. Result:= TensToText(t);
  240. end else
  241. Result:= '';
  242. end;
  243. var
  244. dig, h: Integer;
  245. begin
  246. if n > 0 then begin
  247. dig:= n div 1000;
  248. h:= n mod 1000;
  249. if dig > 0 then begin
  250. if h > 0 then
  251. Result:= HundredsToText(dig) + ' thousand ' + HundredsToText(h)
  252. else
  253. Result:= HundredsToText(dig) + ' thousand';
  254. end else
  255. Result:= HundredsToText(h);
  256. end else
  257. Result:= Number1[0];
  258. end;
  259. procedure Test1;
  260. var
  261. i: Integer;
  262. s: string;
  263. begin
  264. StartLog('Test 1', cTimes + 1);
  265. for i:= 0 to cTimes do begin
  266. NumberToText_V1(s, i);
  267. end;
  268. EndLog('');
  269. end;
  270. procedure Test2;
  271. var
  272. i: Integer;
  273. s: string;
  274. begin
  275. StartLog('Test 2', cTimes + 1);
  276. for i:= 0 to cTimes do begin
  277. NumberToText_V2(s, i);
  278. end;
  279. EndLog('');
  280. end;
  281. procedure Test3;
  282. var
  283. i: Integer;
  284. s: string;
  285. begin
  286. StartLog('Test 3', cTimes + 1);
  287. for i:= 0 to cTimes do begin
  288. s:= NumberToText_V3(i);
  289. end;
  290. EndLog('');
  291. end;
  292. procedure Benchmark;
  293. begin
  294. Test1;
  295. Test2;
  296. Test3;
  297. end;
  298. begin
  299. Benchmark;
  300. end.