class Example
{
public void Print(String msg)
{
if (msg == null)
throw new ArgumentNullException();
PrintInternal(msg);
}
private void PrintInternal(String msg)
{
if (msg == null)
throw new ArgumentNullException();
...
}
}
void PrintValues(IDataReader dataReader)
{
while (dataReader.Read())
{
for (int i = 0; i < dataReader.FieldCount; i++)
{
object value = dataReader.GetValue(i);
PrintValue(value);
}
}
}
void PrintValue(object value)
{
if (value is int)
...
else if (value is long)
...
else if (value is String)
...
else if ...
}
delegate void PrintMethod(object value);
void PrintValues(IDataReader dataReader)
{
PrintMethod[] printers = new PrintMethod[dataReader.FieldCount];
for (int i = 0; i < printers.Length; i++)
{
Type fieldType = dataReader.GetFieldType(i);
if (fieldType == typeof(int))
printers[i] = PrintInt;
else if (fieldType == typeof(long))
printers[i] = PrintLong;
else ...
}
while (dataReader.Read())
{
for (int i = 0; i < printers.Length; i++)
{
object value = dataReader.GetValue(i);
printers[i](value);
}
}
}
int x = a * b;
int y = c ^ d;
int z = x + y;
int w = z - y;
int CompareBytes(byte a, byte b)
{
unchecked
{
int ab = (int)a - (int)b;
int ba = (int)b - (int)a;
return (ab >> 31) | (int)((uint)ba >> 31);
}
}
for (int i = 0; i < a.Length; i++) {
int e = a[i];
}
for (int i = 0; i < a.Count; i++) {
int a = a[i];
int b = a[i];
int c = a[i];
}
int power4(int v)
{
int r = 1;
r *= v;
r *= v;
r *= v;
r *= v;
return r;
}
int power(int v, int N)
{
int r = 1;
// Reduce the number of iterations by 4 times.
for (int loops = N >> 2; loops > 0; loops--)
{
r *= v;
r *= v;
r *= v;
r *= v;
}
// Process the tail.
for (int loops = N & 3; loops > 0; loops--)
{
r *= v;
}
return r;
}
class AsyncWorker
{
volatile int progress;
public int Progress
{
get
{
return progress;
}
}
void DoWork()
{
for (this.progress = 0; this.progress < Count; this.progress++)
{
...
}
}
}
void DoWork(ItemProvider provider)
{
Batch batch = NextFreeBatch();
while (true)
{
Item item = provider.GetNextItem();
batch.AddItem(item);
if (batch.IsFull)
{
EnqueueBatchForAsyncProcessing(batch);
batch = NextFreeBatch();
}
}
}
void EnqueueBatchForAsyncProcessing(Batch batch)
{
lock (this.batchQueue)
this.batchQueue.Enqueue(batch);
}
void ThreadRoutine()
{
while (true)
{
Batch batch = DequeueBatchForAsyncProcessing();
foreach (Item item in batch)
ProcessItem(item);
RecycleBatch(batch);
}
}
Batch DequeueBatchForAsyncProcessing()
{
lock (this.batchQueue)
return this.batchQueue.Dequeue();
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "GetDiskFreeSpaceW")]
static extern bool GetDiskFreeSpace(string lpRootPathName, out int lpSectorsPerCluster, out int lpBytesPerSector, out int lpNumberOfFreeClusters, out int lpTotalNumberOfClusters);
// Each partition has its own cluster size.
public static int GetClusterSize(string path) {
int sectorsPerCluster;
int bytesPerSector;
int freeClusters;
int totalClusters;
int clusterSize = 0;
if (GetDiskFreeSpace(Path.GetPathRoot(path), out sectorsPerCluster, out bytesPerSector, out freeClusters, out totalClusters))
clusterSize = bytesPerSector * sectorsPerCluster;
return clusterSize;
}
MyStruct value;
// Allocate memory buffer.
byte[] buffer = new byte[Marshal.SizeOf(typeof(MyStruct))];
fixed (byte* ptr = buffer)
{
// Serialize value.
*((MyStruct*)ptr) = value;
// Deserialize value;
value = *((MyStruct*)ptr);
}
internal static class ByteArrayReinterpreter
{
private static IntPtr intArrayTypePtr;
unsafe static ByteArrayReinterpreter()
{
int[] intArray = new int[1];
fixed (int* ptr = intArray)
intArrayTypePtr = *(IntPtr*)(((byte*)ptr) - (IntPtr.Size * 2));
intArray = null;
}
public static unsafe int[] AsIntArray(this byte[] array)
{
if ((array.Length & 3) != 0)
throw new ArgumentException("The array length must be multiple of 4.");
object arrayObj = array;
int newLength = array.Length >> 2;
fixed (byte* ptr = array)
{
*(IntPtr*)(((byte*)ptr) - (IntPtr.Size * 2)) = intArrayTypePtr;
*(int*)(((byte*)ptr) - IntPtr.Size) = newLength;
}
return (int[])arrayObj;
}
}
int field;
// Decouple numeric and flags
const int NumericMask = ((1 << 20) - 1);
int numeric = field & NumericMask;
MyFlags flags = (MyFlags)(field >> 20);
// Unite numeric and flags back
field = ((int)flags << 20) | numeric;
struct S
{
byte a;
short b;
short c;
}
struct S
{
// offset: 0, size: 4
byte a;
byte __padding_byte_1;
byte __padding_byte_2;
byte __padding_byte_3;
// offset: 4, size: 4
short b;
byte __padding_byte_4;
byte __padding_byte_5;
// offset: 8, size: 4
short c;
byte __padding_byte_6;
byte __padding_byte_7;
// total size: 12
}
bool Equals(Guid g)
{
return g._a == this._a && g._b == this._b && g._c == this._c && g._d == this._d
&& g._e == this._e && g._f == this._f && g._g == this._g && g._h == this._h
&& g._i == this._i && g._j == this._j && g._k == this._k;
}
unsafe bool Equals(Guid g)
{
fixed (Guid* pg = &this)
{
int* p1 = (int*)pg;
int* p2 = (int*)&g;
return p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2] && p1[3] == p2[3];
}
}
unsafe bool Equals(Guid g)
{
fixed (Guid* pg = &this)
{
long* p1 = (long*)pg;
long* p2 = (long*)&g;
return p1[0] == p2[0] && p1[1] == p2[1];
}
}
bool CompareGuids(Guid g1, Guid g2)
bool CompareGuids(ref Guid g1, ref Guid g2)
int Multiply(int a, int b)
{
return a * b;
}
void Foo()
{
int a = 4;
int b = 5;
int r = Multiply(a, b);
}
class X
{
virtual void A();
virtual void B();
}
class Y : X
{
override void B();
}
sealed class Y : X
{
override void B();
}
void Slow(X x)
{
x.B();
}
void Fast(Y y)
{
y.B();
}
HashSet<string> keywords;
String tokenText;
bool isKeyword = keywords.Contains(tokenText.ToUpperInvariant());
bool IsKeyword(String tokenText)
{
int hashCode = 0;
for (int i = 0; i < tokenText.Length; i++)
{
int c = (int)tokenText[i];
// check upper bound
if (c > 'z')
return false;
// to upper case for Latin letters
if (c >= 'a')
c ^= 0x20;
// a keyword must be of Latin letters, numbers, and underscore
if ( ! ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'))
return false;
// update hash code
hashCode = hashCode <op> c;
}
return keywords.Contain(hashCode);
}
class Multiplier
{
public int a, b;
public int Multiply() { return a * b; }
}
(, ) | 24 | 6 | 4 |
(, ) | 16 | 2 | 8 |
â (, ) 8 99.9% â , , «» . , 75% SqlDataReader, 25% â . | 10 | 2.2 | 4.5 |
, â (, ; , MiB) | 6 125 MiB | 1.8 98 MiB | 3.3 - |
, (, ; , MiB) , . , . | 12 36 MiB | 2.2 24 MiB | 5.4 - |
T-SQL â , (, ; , MiB) 2 98 MiB 187 MiB â SSD | 21 245 MiB | 2 187 MiB | 10.5 - |
T-SQL , (, ) T-SQL , SQL Server. , SQL SqlCommand . | 2 27 | 1 26 | 1.7 |
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
partial class Program
{
#region Keywords 1 - ToUpperInvariant
static HashSet<String> keywords1;
static void InitKeywords1()
{
keywords1 = new HashSet<string>();
keywords1.Add("ABSOLUTE");
keywords1.Add("ACTION");
keywords1.Add("ADA");
keywords1.Add("ADD");
keywords1.Add("ADMIN");
keywords1.Add("AFTER");
keywords1.Add("AGGREGATE");
keywords1.Add("ALIAS");
keywords1.Add("ALL");
keywords1.Add("ALLOCATE");
keywords1.Add("ALTER");
keywords1.Add("AND");
keywords1.Add("ANY");
keywords1.Add("ARE");
keywords1.Add("ARRAY");
keywords1.Add("AS");
keywords1.Add("ASC");
keywords1.Add("ASENSITIVE");
keywords1.Add("ASSERTION");
keywords1.Add("ASYMMETRIC");
keywords1.Add("AT");
keywords1.Add("ATOMIC");
keywords1.Add("AUTHORIZATION");
keywords1.Add("AVG");
keywords1.Add("BACKUP");
keywords1.Add("BEFORE");
keywords1.Add("BEGIN");
keywords1.Add("BETWEEN");
keywords1.Add("BIGINT");
keywords1.Add("BINARY");
keywords1.Add("BIT");
keywords1.Add("BIT_LENGTH");
keywords1.Add("BLOB");
keywords1.Add("BOOLEAN");
keywords1.Add("BOTH");
keywords1.Add("BREADTH");
keywords1.Add("BREAK");
keywords1.Add("BROWSE");
keywords1.Add("BULK");
keywords1.Add("BY");
keywords1.Add("CALL");
keywords1.Add("CALLED");
keywords1.Add("CARDINALITY");
keywords1.Add("CASCADE");
keywords1.Add("CASCADED");
keywords1.Add("CASE");
keywords1.Add("CAST");
keywords1.Add("CATALOG");
keywords1.Add("CHAR");
keywords1.Add("CHAR_LENGTH");
keywords1.Add("CHARACTER");
keywords1.Add("CHARACTER_LENGTH");
keywords1.Add("CHECK");
keywords1.Add("CHECKPOINT");
keywords1.Add("CLASS");
keywords1.Add("CLOB");
keywords1.Add("CLOSE");
keywords1.Add("CLUSTERED");
keywords1.Add("COALESCE");
keywords1.Add("COLLATE");
keywords1.Add("COLLATION");
keywords1.Add("COLLECT");
keywords1.Add("COLUMN");
keywords1.Add("COMMIT");
keywords1.Add("COMPLETION");
keywords1.Add("COMPUTE");
keywords1.Add("CONDITION");
keywords1.Add("CONNECT");
keywords1.Add("CONNECTION");
keywords1.Add("CONSTRAINT");
keywords1.Add("CONSTRAINTS");
keywords1.Add("CONSTRUCTOR");
keywords1.Add("CONTAINS");
keywords1.Add("CONTAINSTABLE");
keywords1.Add("CONTINUE");
keywords1.Add("CONVERT");
keywords1.Add("CORR");
keywords1.Add("CORRESPONDING");
keywords1.Add("COUNT");
keywords1.Add("COVAR_POP");
keywords1.Add("COVAR_SAMP");
keywords1.Add("CREATE");
keywords1.Add("CROSS");
keywords1.Add("CUBE");
keywords1.Add("CUME_DIST");
keywords1.Add("CURRENT");
keywords1.Add("CURRENT_CATALOG");
keywords1.Add("CURRENT_DATE");
keywords1.Add("CURRENT_DEFAULT_TRANSFORM_GROUP");
keywords1.Add("CURRENT_PATH");
keywords1.Add("CURRENT_ROLE");
keywords1.Add("CURRENT_SCHEMA");
keywords1.Add("CURRENT_TIME");
keywords1.Add("CURRENT_TIMESTAMP");
keywords1.Add("CURRENT_TRANSFORM_GROUP_FOR_TYPE");
keywords1.Add("CURRENT_USER");
keywords1.Add("CURSOR");
keywords1.Add("CYCLE");
keywords1.Add("DATA");
keywords1.Add("DATABASE");
keywords1.Add("DATE");
keywords1.Add("DATETIME");
keywords1.Add("DATETIME2");
keywords1.Add("DATETIMEOFFSET");
keywords1.Add("DAY");
keywords1.Add("DBCC");
keywords1.Add("DEALLOCATE");
keywords1.Add("DEC");
keywords1.Add("DECIMAL");
keywords1.Add("DECLARE");
keywords1.Add("DEFAULT");
keywords1.Add("DEFERRABLE");
keywords1.Add("DEFERRED");
keywords1.Add("DELETE");
keywords1.Add("DENY");
keywords1.Add("DEPTH");
keywords1.Add("DEREF");
keywords1.Add("DESC");
keywords1.Add("DESCRIBE");
keywords1.Add("DESCRIPTOR");
keywords1.Add("DESTROY");
keywords1.Add("DESTRUCTOR");
keywords1.Add("DETERMINISTIC");
keywords1.Add("DIAGNOSTICS");
keywords1.Add("DICTIONARY");
keywords1.Add("DISCONNECT");
keywords1.Add("DISK");
keywords1.Add("DISTINCT");
keywords1.Add("DISTRIBUTED");
keywords1.Add("DOMAIN");
keywords1.Add("DOUBLE");
keywords1.Add("DROP");
keywords1.Add("DUMP");
keywords1.Add("DYNAMIC");
keywords1.Add("EACH");
keywords1.Add("ELEMENT");
keywords1.Add("ELSE");
keywords1.Add("END");
keywords1.Add("END-EXEC");
keywords1.Add("EQUALS");
keywords1.Add("ERRLVL");
keywords1.Add("ESCAPE");
keywords1.Add("EVERY");
keywords1.Add("EXCEPT");
keywords1.Add("EXCEPTION");
keywords1.Add("EXEC");
keywords1.Add("EXECUTE");
keywords1.Add("EXISTS");
keywords1.Add("EXIT");
keywords1.Add("EXTERNAL");
keywords1.Add("EXTRACT");
keywords1.Add("FALSE");
keywords1.Add("FETCH");
keywords1.Add("FILE");
keywords1.Add("FILLFACTOR");
keywords1.Add("FILTER");
keywords1.Add("FIRST");
keywords1.Add("FLOAT");
keywords1.Add("FOR");
keywords1.Add("FOREIGN");
keywords1.Add("FORTRAN");
keywords1.Add("FOUND");
keywords1.Add("FREE");
keywords1.Add("FREETEXT");
keywords1.Add("FREETEXTTABLE");
keywords1.Add("FROM");
keywords1.Add("FULL");
keywords1.Add("FULLTEXTTABLE");
keywords1.Add("FUNCTION");
keywords1.Add("FUSION");
keywords1.Add("GENERAL");
keywords1.Add("GEOGRAPHY");
keywords1.Add("GEOMETRY");
keywords1.Add("GET");
keywords1.Add("GLOBAL");
keywords1.Add("GO");
keywords1.Add("GOTO");
keywords1.Add("GRANT");
keywords1.Add("GROUP");
keywords1.Add("GROUPING");
keywords1.Add("HAVING");
keywords1.Add("HIERACHYID");
keywords1.Add("HOLD");
keywords1.Add("HOLDLOCK");
keywords1.Add("HOST");
keywords1.Add("HOUR");
keywords1.Add("IDENTITY");
keywords1.Add("IDENTITY_INSERT");
keywords1.Add("IDENTITYCOL");
keywords1.Add("IF");
keywords1.Add("IGNORE");
keywords1.Add("IMAGE");
keywords1.Add("IMMEDIATE");
keywords1.Add("IN");
keywords1.Add("INCLUDE");
keywords1.Add("INDEX");
keywords1.Add("INDICATOR");
keywords1.Add("INITIALIZE");
keywords1.Add("INITIALLY");
keywords1.Add("INNER");
keywords1.Add("INOUT");
keywords1.Add("INPUT");
keywords1.Add("INSENSITIVE");
keywords1.Add("INSERT");
keywords1.Add("INT");
keywords1.Add("INTEGER");
keywords1.Add("INTERSECT");
keywords1.Add("INTERSECTION");
keywords1.Add("INTERVAL");
keywords1.Add("INTO");
keywords1.Add("IS");
keywords1.Add("ISOLATION");
keywords1.Add("ITERATE");
keywords1.Add("JOIN");
keywords1.Add("KEY");
keywords1.Add("KILL");
keywords1.Add("LANGUAGE");
keywords1.Add("LARGE");
keywords1.Add("LAST");
keywords1.Add("LATERAL");
keywords1.Add("LEADING");
keywords1.Add("LEFT");
keywords1.Add("LESS");
keywords1.Add("LEVEL");
keywords1.Add("LIKE");
keywords1.Add("LIKE_REGEX");
keywords1.Add("LIMIT");
keywords1.Add("LINENO");
keywords1.Add("LN");
keywords1.Add("LOAD");
keywords1.Add("LOCAL");
keywords1.Add("LOCALTIME");
keywords1.Add("LOCALTIMESTAMP");
keywords1.Add("LOCATOR");
keywords1.Add("LOWER");
keywords1.Add("MAP");
keywords1.Add("MATCH");
keywords1.Add("MAX");
keywords1.Add("MEMBER");
keywords1.Add("MERGE");
keywords1.Add("METHOD");
keywords1.Add("MIN");
keywords1.Add("MINUTE");
keywords1.Add("MOD");
keywords1.Add("MODIFIES");
keywords1.Add("MODIFY");
keywords1.Add("MODULE");
keywords1.Add("MONEY");
keywords1.Add("MONTH");
keywords1.Add("MULTISET");
keywords1.Add("NAMES");
keywords1.Add("NATIONAL");
keywords1.Add("NATURAL");
keywords1.Add("NCHAR");
keywords1.Add("NCLOB");
keywords1.Add("NEW");
keywords1.Add("NEXT");
keywords1.Add("NO");
keywords1.Add("NOCHECK");
keywords1.Add("NOCOUNT");
keywords1.Add("NONCLUSTERED");
keywords1.Add("NONE");
keywords1.Add("NORMALIZE");
keywords1.Add("NOT");
keywords1.Add("NTEXT");
keywords1.Add("NULL");
keywords1.Add("NULLIF");
keywords1.Add("NUMERIC");
keywords1.Add("NVARCHAR");
keywords1.Add("OBJECT");
keywords1.Add("OCCURRENCES_REGEX");
keywords1.Add("OCTET_LENGTH");
keywords1.Add("OF");
keywords1.Add("OFF");
keywords1.Add("OFFSETS");
keywords1.Add("OLD");
keywords1.Add("ON");
keywords1.Add("ONLY");
keywords1.Add("OPEN");
keywords1.Add("OPENDATASOURCE");
keywords1.Add("OPENQUERY");
keywords1.Add("OPENROWSET");
keywords1.Add("OPENXML");
keywords1.Add("OPERATION");
keywords1.Add("OPTION");
keywords1.Add("OR");
keywords1.Add("ORDER");
keywords1.Add("ORDINALITY");
keywords1.Add("OUT");
keywords1.Add("OUTER");
keywords1.Add("OUTPUT");
keywords1.Add("OVER");
keywords1.Add("OVERLAPS");
keywords1.Add("OVERLAY");
keywords1.Add("PAD");
keywords1.Add("PARAMETER");
keywords1.Add("PARAMETERS");
keywords1.Add("PARTIAL");
keywords1.Add("PARTITION");
keywords1.Add("PASCAL");
keywords1.Add("PATH");
keywords1.Add("PERCENT");
keywords1.Add("PERCENT_RANK");
keywords1.Add("PERCENTILE_CONT");
keywords1.Add("PERCENTILE_DISC");
keywords1.Add("PIVOT");
keywords1.Add("PLAN");
keywords1.Add("POSITION");
keywords1.Add("POSITION_REGEX");
keywords1.Add("POSTFIX");
keywords1.Add("PRECISION");
keywords1.Add("PREFIX");
keywords1.Add("PREORDER");
keywords1.Add("PREPARE");
keywords1.Add("PRESERVE");
keywords1.Add("PRIMARY");
keywords1.Add("PRINT");
keywords1.Add("PRIOR");
keywords1.Add("PRIVILEGES");
keywords1.Add("PROC");
keywords1.Add("PROCEDURE");
keywords1.Add("PUBLIC");
keywords1.Add("RAISERROR");
keywords1.Add("RANGE");
keywords1.Add("READ");
keywords1.Add("READS");
keywords1.Add("READTEXT");
keywords1.Add("REAL");
keywords1.Add("RECONFIGURE");
keywords1.Add("RECURSIVE");
keywords1.Add("REF");
keywords1.Add("REFERENCES");
keywords1.Add("REFERENCING");
keywords1.Add("REGR_AVGX");
keywords1.Add("REGR_AVGY");
keywords1.Add("REGR_COUNT");
keywords1.Add("REGR_INTERCEPT");
keywords1.Add("REGR_R2");
keywords1.Add("REGR_SLOPE");
keywords1.Add("REGR_SXX");
keywords1.Add("REGR_SXY");
keywords1.Add("REGR_SYY");
keywords1.Add("RELATIVE");
keywords1.Add("RELEASE");
keywords1.Add("REPLICATION");
keywords1.Add("RESTORE");
keywords1.Add("RESTRICT");
keywords1.Add("RESULT");
keywords1.Add("RETURN");
keywords1.Add("RETURNS");
keywords1.Add("REVERT");
keywords1.Add("REVOKE");
keywords1.Add("RIGHT");
keywords1.Add("ROLE");
keywords1.Add("ROLLBACK");
keywords1.Add("ROLLUP");
keywords1.Add("ROUTINE");
keywords1.Add("ROW");
keywords1.Add("ROWCOUNT");
keywords1.Add("ROWGUIDCOL");
keywords1.Add("ROWS");
keywords1.Add("ROWVERSION");
keywords1.Add("RULE");
keywords1.Add("SAVE");
keywords1.Add("SAVEPOINT");
keywords1.Add("SCHEMA");
keywords1.Add("SCOPE");
keywords1.Add("SCROLL");
keywords1.Add("SEARCH");
keywords1.Add("SECOND");
keywords1.Add("SECTION");
keywords1.Add("SECURITYAUDIT");
keywords1.Add("SELECT");
keywords1.Add("SENSITIVE");
keywords1.Add("SEQUENCE");
keywords1.Add("SESSION");
keywords1.Add("SESSION_USER");
keywords1.Add("SET");
keywords1.Add("SETS");
keywords1.Add("SETUSER");
keywords1.Add("SHUTDOWN");
keywords1.Add("SIMILAR");
keywords1.Add("SIZE");
keywords1.Add("SMALLDATETIME");
keywords1.Add("SMALLINT");
keywords1.Add("SMALLMONEY");
keywords1.Add("SOME");
keywords1.Add("SPACE");
keywords1.Add("SPECIFIC");
keywords1.Add("SPECIFICTYPE");
keywords1.Add("SQL");
keywords1.Add("SQL_VARIANT");
keywords1.Add("SQLCA");
keywords1.Add("SQLCODE");
keywords1.Add("SQLERROR");
keywords1.Add("SQLEXCEPTION");
keywords1.Add("SQLSTATE");
keywords1.Add("SQLWARNING");
keywords1.Add("START");
keywords1.Add("STATE");
keywords1.Add("STATEMENT");
keywords1.Add("STATIC");
keywords1.Add("STATISTICS");
keywords1.Add("STDDEV_POP");
keywords1.Add("STDDEV_SAMP");
keywords1.Add("STRUCTURE");
keywords1.Add("SUBMULTISET");
keywords1.Add("SUBSTRING");
keywords1.Add("SUBSTRING_REGEX");
keywords1.Add("SUM");
keywords1.Add("SYMMETRIC");
keywords1.Add("SYSNAME");
keywords1.Add("SYSTEM");
keywords1.Add("SYSTEM_USER");
keywords1.Add("TABLE");
keywords1.Add("TABLESAMPLE");
keywords1.Add("TEMPORARY");
keywords1.Add("TERMINATE");
keywords1.Add("TEXT");
keywords1.Add("TEXTSIZE");
keywords1.Add("THAN");
keywords1.Add("THEN");
keywords1.Add("TIME");
keywords1.Add("TIMESTAMP");
keywords1.Add("TIMEZONE_HOUR");
keywords1.Add("TIMEZONE_MINUTE");
keywords1.Add("TINYINT");
keywords1.Add("TO");
keywords1.Add("TOP");
keywords1.Add("TRAILING");
keywords1.Add("TRAN");
keywords1.Add("TRANSACTION");
keywords1.Add("TRANSLATE");
keywords1.Add("TRANSLATE_REGEX");
keywords1.Add("TRANSLATION");
keywords1.Add("TREAT");
keywords1.Add("TRIGGER");
keywords1.Add("TRIM");
keywords1.Add("TRUE");
keywords1.Add("TRUNCATE");
keywords1.Add("TSEQUAL");
keywords1.Add("UESCAPE");
keywords1.Add("UNDER");
keywords1.Add("UNION");
keywords1.Add("UNIQUE");
keywords1.Add("UNIQUEIDENTIFIER");
keywords1.Add("UNKNOWN");
keywords1.Add("UNNEST");
keywords1.Add("UNPIVOT");
keywords1.Add("UPDATE");
keywords1.Add("UPDATETEXT");
keywords1.Add("UPPER");
keywords1.Add("USAGE");
keywords1.Add("USE");
keywords1.Add("USER");
keywords1.Add("USING");
keywords1.Add("VALUE");
keywords1.Add("VALUES");
keywords1.Add("VAR_POP");
keywords1.Add("VAR_SAMP");
keywords1.Add("VARBINARY");
keywords1.Add("VARCHAR");
keywords1.Add("VARIABLE");
keywords1.Add("VARYING");
keywords1.Add("VIEW");
keywords1.Add("WAITFOR");
keywords1.Add("WHEN");
keywords1.Add("WHENEVER");
keywords1.Add("WHERE");
keywords1.Add("WHILE");
keywords1.Add("WIDTH_BUCKET");
keywords1.Add("WINDOW");
keywords1.Add("WITH");
keywords1.Add("WITHIN");
keywords1.Add("WITHOUT");
keywords1.Add("WORK");
keywords1.Add("WRITE");
keywords1.Add("WRITETEXT");
keywords1.Add("XML");
keywords1.Add("XMLAGG");
keywords1.Add("XMLATTRIBUTES");
keywords1.Add("XMLBINARY");
keywords1.Add("XMLCAST");
keywords1.Add("XMLCOMMENT");
keywords1.Add("XMLCONCAT");
keywords1.Add("XMLDOCUMENT");
keywords1.Add("XMLELEMENT");
keywords1.Add("XMLEXISTS");
keywords1.Add("XMLFOREST");
keywords1.Add("XMLITERATE");
keywords1.Add("XMLNAMESPACES");
keywords1.Add("XMLPARSE");
keywords1.Add("XMLPI");
keywords1.Add("XMLQUERY");
keywords1.Add("XMLSERIALIZE");
keywords1.Add("XMLTABLE");
keywords1.Add("XMLTEXT");
keywords1.Add("XMLVALIDATE");
keywords1.Add("YEAR");
keywords1.Add("ZONE");
}
static bool IsKeyword1(String tokenText)
{
return keywords1.Contains(tokenText.ToUpperInvariant());
}
#endregion
#region Keywords 2 - StringComparer
static HashSet<String> keywords2;
static void InitKeywords2()
{
keywords2 = new HashSet<string>(keywords1, StringComparer.OrdinalIgnoreCase);
}
static bool IsKeyword2(String tokenText)
{
return keywords2.Contains(tokenText);
}
#endregion
#region Keywords 3 - Good optimized
static IntPtr gpCaseMapping;
static IntPtr gpKeywords3;
unsafe static void InitKeywords3()
{
gpKeywords3 = Marshal.AllocCoTaskMem(1293 * 4 * 4);
int* pHashset3 = (int*)gpKeywords3;
for (int i = 0; i < 1293 * 4; i++)
pHashset3[i] = 0;
foreach (String keyword in keywords1)
{
fixed (char* pKeyword = keyword)
{
int hashCode = keyword.GetHashCode();
int index = (int)(((uint)hashCode % 1293) << 2);
if (pHashset3[index] != 0)
index += 2;
if (pHashset3[index] != 0)
throw new Exception("Solve the collision.");
pHashset3[index] = hashCode;
pHashset3[index + 1] = (int)pKeyword[0] | ((int)pKeyword[1] << 8) | ((int)pKeyword[2] << 16) | ((int)pKeyword[3] << 24);
}
}
gpCaseMapping = Marshal.AllocCoTaskMem(65536);
byte* pCaseMapping = (byte*)gpCaseMapping;
for (int i = 0; i < 65536; i++)
pCaseMapping[i] = 0;
for (int i = 'A'; i <= 'Z'; i++)
pCaseMapping[i] = (byte)i;
for (int i = 'a'; i <= 'z'; i++)
pCaseMapping[i] = (byte)(i ^ 0x20);
pCaseMapping['2'] = (byte)'2';
pCaseMapping['-'] = (byte)'-';
pCaseMapping['_'] = (byte)'_';
}
unsafe static bool IsKeyword3(String tokenText)
{
unchecked
{
fixed (char* pString = tokenText)
{
byte* pCaseMapping = (byte*)gpCaseMapping;
int num1 = 5381;
int num2 = num1;
int c1;
int c2;
char* ptr = pString;
int seq = 0;
if (tokenText.Length >= 4)
{
c1 = (int)(*(ushort*)ptr);
c2 = (int)(*(ushort*)(ptr + 1));
c1 = pCaseMapping[c1];
c2 = pCaseMapping[c2];
if (c1 == 0 || c2 == 0)
return false;
seq = (c2 << 8) | c1;
num1 = ((num1 << 5) + num1 ^ c1);
num2 = ((num2 << 5) + num2 ^ c2);
ptr += 2;
c1 = (int)(*(ushort*)ptr);
c2 = (int)(*(ushort*)(ptr + 1));
c1 = pCaseMapping[c1];
c2 = pCaseMapping[c2];
if (c1 == 0 || c2 == 0)
return false;
seq |= (c2 << 24) | (c1 << 16);
num1 = ((num1 << 5) + num1 ^ c1);
num2 = ((num2 << 5) + num2 ^ c2);
ptr += 2;
for (int loops = (tokenText.Length >> 1) - 2; loops > 0; loops--, ptr += 2)
{
c1 = (int)(*(ushort*)ptr);
c2 = (int)(*(ushort*)(ptr + 1));
c1 = pCaseMapping[c1];
c2 = pCaseMapping[c2];
if (c1 == 0 || c2 == 0)
return false;
num1 = ((num1 << 5) + num1 ^ c1);
num2 = ((num2 << 5) + num2 ^ c2);
}
if ((tokenText.Length & 1) != 0)
{
c1 = (int)(*(ushort*)ptr);
c1 = pCaseMapping[c1];
if (c1 == 0)
return false;
num1 = ((num1 << 5) + num1 ^ c1);
}
}
else if (tokenText.Length == 3)
{
c1 = (int)(*(ushort*)ptr);
c2 = (int)(*(ushort*)(ptr + 1));
c1 = pCaseMapping[c1];
c2 = pCaseMapping[c2];
if (c1 == 0 || c2 == 0)
return false;
seq = (c2 << 8) | c1;
num1 = ((num1 << 5) + num1 ^ c1);
num2 = ((num2 << 5) + num2 ^ c2);
c1 = (int)(*(ushort*)(ptr + 2));
c1 = pCaseMapping[c1];
if (c1 == 0)
return false;
seq |= (c1 << 16);
num1 = ((num1 << 5) + num1 ^ c1);
}
else if (tokenText.Length == 2)
{
c1 = (int)(*(ushort*)ptr);
c2 = (int)(*(ushort*)(ptr + 1));
c1 = pCaseMapping[c1];
c2 = pCaseMapping[c2];
if (c1 == 0 || c2 == 0)
return false;
seq = (c2 << 8) | c1;
num1 = ((num1 << 5) + num1 ^ c1);
num2 = ((num2 << 5) + num2 ^ c2);
ptr += 2;
}
else
{
return false;
}
int hashCode = num1 + num2 * 1566083941;
int index = (int)(((uint)hashCode % 1293) << 2);
int* pHashset3 = (int*)gpKeywords3;
return (pHashset3[index + 0] == hashCode && pHashset3[index + 1] == seq)
|| (pHashset3[index + 2] == hashCode && pHashset3[index + 3] == seq);
}
}
}
#endregion
#region Test Data
static String[] TestTokens = new String[] {
"DECLARE", "@lang", "sysname",
"SELECT", "TOP", "@lang", "Alias", "FROM", "sys", "syslanguages", "WHERE", "lcid",
"IF", "@lang", "IS", "NOT", "NULL", "SET", "LANGUAGE", "@lang",
"SET", "ARITHABORT", "ANSI_PADDING", "ANSI_WARNINGS", "QUOTED_IDENTIFIER",
"NOCOUNT", "CONCAT_NULL_YIELDS_NULL", "ANSI_NULLS", "ON",
"SET", "NUMERIC_ROUNDABORT", "IMPLICIT_TRANSACTIONS", "XACT_ABORT", "OFF",
"SET", "DATEFORMAT", "dmy",
"USE", "AdventureWorks2008R2",
"GO",
"INSERT", "Sales", "SalesOrderHeader", "SalesOrderID", "RevisionNumber", "OrderDate", "DueDate", "ShipDate",
"Status", "OnlineOrderFlag", "PurchaseOrderNumber", "AccountNumber", "CustomerID", "SalesPersonID", "TerritoryID",
"BillToAddressID", "ShipToAddressID", "ShipMethodID", "CreditCardID", "CreditCardApprovalCode", "CurrencyRateID",
"SubTotal", "TaxAmt", "Freight", "Comment", "rowguid", "ModifiedDate", "VALUES",
"ALTER", "TABLE", "dbo", "DatabaseLog", "ADD", "CONSTRAINT", "PK_DatabaseLog_DatabaseLogID", "PRIMARY", "KEY", "NONCLUSTERED",
"DatabaseLogID", "ASC", "WITH", "DATA_COMPRESSION", "NONE",
"EXEC", "sp_addextendedproperty", "dbo", "DatabaseLog", "PK_DatabaseLog_DatabaseLogID",
"GO", "IF", "@@ERROR", "OR", "TRANCOUNT", "BEGIN", "IF", "@@TRANCOUNT", "ROLLBACK", "SET", "NOEXEC", "ON", "END",
"GO", "DBCC", "CHECKIDENT", "RESEED", "GO", "IF", "@@ERROR", "@@TRANCOUNT", "BEGIN", "IF", "@@TRANCOUNT", "ROLLBACK", "SET", "NOEXEC", "ON", "END", "GO"
};
#endregion
#region Timing
static long _timestamp;
static void StartTiming()
{
_timestamp = Stopwatch.GetTimestamp();
}
static double EndTiming()
{
return (double)(Stopwatch.GetTimestamp() - _timestamp) / (double)Stopwatch.Frequency;
}
#endregion
unsafe static void DoLexerTests()
{
int testCount = 100000;
int matchCount = 0;
double time;
// Test 1
InitKeywords1();
StartTiming();
for (int t = testCount; t > 0; t--)
{
matchCount = 0;
for (int i = 0; i < TestTokens.Length; i++)
{
String identifier = TestTokens[i];
if (IsKeyword1(identifier))
matchCount++;
}
}
time = EndTiming();
Console.WriteLine("Test 1 - ToUpper");
Console.WriteLine("Time: " + time);
Console.WriteLine("Matches: " + matchCount);
Console.WriteLine();
// Test 2
InitKeywords2();
StartTiming();
for (int t = testCount; t > 0; t--)
{
matchCount = 0;
for (int i = 0; i < TestTokens.Length; i++)
{
String identifier = TestTokens[i];
if (IsKeyword2(identifier))
matchCount++;
}
}
time = EndTiming();
Console.WriteLine("Test 2 - StringComparer");
Console.WriteLine("Time: " + time);
Console.WriteLine("Matches: " + matchCount);
Console.WriteLine();
// Test 3
InitKeywords3();
StartTiming();
for (int t = testCount; t > 0; t--)
{
matchCount = 0;
for (int i = 0; i < TestTokens.Length; i++)
{
String identifier = TestTokens[i];
if (IsKeyword3(identifier))
matchCount++;
}
}
time = EndTiming();
Console.WriteLine("Test 3 - Optimized Code");
Console.WriteLine("Time: " + time);
Console.WriteLine("Matches: " + matchCount);
Console.WriteLine();
}
}
}
ToUpperInvariant | 2330 |
IEqualityComparer | 661 |
239 |
, ,
Source: https://habr.com/ru/post/165729/
All Articles