MODULE CountChars6; (* ========================================================================= Example GPCP .NET Console Program Compare the relative efficiency of a CASE statement with an equivalent sequence of IF THEN ELSE statements. The number of occurrences of different categories of characters in a huge string (1 million characters) is counted using both techniques. The processing time of each is measured using .NET timing procedures which have microsecond resolution. Author : Chris Burrows Created: Jan 2007 (c) 2007-2008 CFB Software http://www.cfbsoftware.com/gpcp ========================================================================= *) IMPORT Dia := "[System]System.Diagnostics", Out, CPmain; CONST TestLimit = 1000000; VAR s: ARRAY TestLimit + 1 OF CHAR; i: INTEGER; timer: Dia.Stopwatch; PROCEDURE WriteCount(count: INTEGER; IN msg: ARRAY OF CHAR); BEGIN Out.Int(count, 8); Out.String(msg); Out.Ln() END WriteCount; PROCEDURE CountChars1(IN s: ARRAY OF CHAR); VAR i, vowels, letters, capitals, digits, others: INTEGER; ch: CHAR; timer: Dia.Stopwatch; BEGIN vowels := 0; letters := 0; capitals := 0; digits := 0; others := 0; timer := Dia.Stopwatch.StartNew(); FOR i := 0 TO LEN(s$) - 1 DO ch := s[i]; IF (ch >= 'a') & (ch <= 'z') THEN INC(letters); IF (ch = 'a') OR (ch = 'e') OR (ch = 'i') OR (ch = 'o') OR (ch = 'u') THEN INC(vowels) END ELSIF (ch >= 'A') & (ch <= 'Z') THEN INC(letters); INC(capitals); IF (ch = 'A') OR (ch = 'E') OR (ch = 'I') OR (ch = 'O') OR (ch = 'U') THEN INC(vowels) END ELSIF (ch >= '0') & (ch <= '9') THEN INC(digits) ELSE INC(others) END END; Out.String(timer.get_Elapsed().ToString()); Out.Ln(); WriteCount(letters, ' letters'); WriteCount(capitals, ' capitals'); WriteCount(vowels, ' vowels'); WriteCount(letters - vowels, ' consonants'); WriteCount(digits, ' digits'); WriteCount(others, ' others'); Out.Ln() END CountChars1; PROCEDURE CountChars2(IN s: ARRAY OF CHAR); VAR i, vowels, letters, capitals, digits, others: INTEGER; timer: Dia.Stopwatch; BEGIN vowels := 0; letters := 0; capitals := 0; digits := 0; others := 0; timer := Dia.Stopwatch.StartNew(); FOR i := 0 TO LEN(s$) - 1 DO CASE s[i] OF 'a', 'e', 'i', 'o', 'u': INC(vowels); INC(letters) | 'A', 'E', 'I', 'O', 'U': INC(vowels); INC(letters); INC(capitals) | 'b'..'d', 'f'..'h', 'j'..'n', 'p'..'t', 'v'..'z': INC(letters) | 'B'..'D', 'F'..'H', 'J'..'N', 'P'..'T', 'V'..'Z': INC(letters); INC(capitals) | '0'..'9': INC(digits) ELSE INC(others) END END; Out.String(timer.get_Elapsed().ToString()); Out.Ln(); WriteCount(letters, ' letters'); WriteCount(capitals, ' capitals'); WriteCount(vowels, ' vowels'); WriteCount(letters - vowels, ' consonants'); WriteCount(digits, ' digits'); WriteCount(others, ' others'); Out.Ln() END CountChars2; BEGIN NEW(timer); FOR i := 0 TO TestLimit - 1 DO s[i] := CHR(i MOD 255 + 1) END; s[TestLimit] := 0X; CountChars1(s); CountChars2(s) END CountChars6.