Tuesday, June 23, 2020

C# - Fastest way to find a number/integer in a string

After an extensive review of getting a lead integer from a string, see my post here.

Here's the fastest way in C# to get the 1st integer in a string. This is not Unicode compliant, but works for English speaking populations using ASCII numerals 0-9.

Code

using System;
using System.Diagnostics;
using System.Text; 
using System.Text.RegularExpressions; 

public static class StringExtensions {
 
        /// <summary>
        /// Fastest way to to find 1st number in a string and convert it into an integer
        /// </summary>
        /// <param name="intStr"></param>
        /// <returns></returns>
        //  https://metadataconsulting.blogspot.com/2020/06/CSharp-Fastest-way-to-find-a-number-or-integer-in-a-string.html
        public static int GetFirstIntFast(this string intStr)
        {
 
            int sum = 0; //must be zero
            char[] n = intStr.ToCharArray(); //fastest way to index a string
            int idxFirstDigit = -1;  

            for (int i = 0; i < n.Length; i++)
            {
                if (n[i] >= 48 && n[i] <= 57)  //'0'=48 and '9'=57 get lead number only
                {
                    if (idxFirstDigit == -1) idxFirstDigit = i; 
                    int z = sum * 10 + (n[i] - 48);
                    if (z < 0) //we get into negative, if over int.MaxValue
                        return int.MaxValue; //or throw error
                    sum = z;
                }
                else if (idxFirstDigit>-1)
                    break;
                    //return int.MinValue; //or throw error
            }

            if (intStr.IndexOf('-') == idxFirstDigit-1) //chek for neg sign
               sum *= -1;
            
            return sum;

        }

}

public class Program
{
 
 public static void Main()
 {
  
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Console.WriteLine("aaaa12451a 1".GetFirstIntFast());
            sw.Stop();
            Console.WriteLine(sw.ElapsedTicks.ToString() + " ticks");
            sw.Reset();
            sw.Start();
            Console.WriteLine("aaaaa-12452a 2".GetFirstIntFast());
            sw.Stop();
            Console.WriteLine(sw.ElapsedTicks.ToString() + " ticks");
            sw.Reset();
            sw.Start();
            Console.WriteLine("aaaaaa+12453a 3".GetFirstIntFast());
            sw.Stop();
            Console.WriteLine(sw.ElapsedTicks.ToString() + " ticks");
            sw.Reset();
            sw.Start();
            Console.WriteLine("aaaaaa".GetFirstIntFast());
            sw.Stop();
            Console.WriteLine(sw.ElapsedTicks.ToString() + " ticks");
            Console.WriteLine("1122222222222222222222".GetFirstIntFast());
            sw.Stop();
            Console.WriteLine(sw.ElapsedTicks.ToString() + " ticks");
 
 }
}

Monday, June 22, 2020

How to setup font size for GNU Emacs for Windows

Luckily this is one of the easier setting to change. The Default Font for GNU Emacs for Windows, is available under Options -> Set Default Font...

Emacs GUI client for Windows is free download here.
































Choose your font family and size. And remember to save your options. 


















































Thursday, June 18, 2020

C# .Net - Fast Modulo solutions, including bit-wise and additive

Expanding on my last post, these are fast possible alternative implementations of modulo in C# .Net.

I added the simple additive modulo operation that adds a variable in a loop until it exceeds the amount. The bit-wise shifting Russian Peasant implementation of modulo is also here.
In C language, Russian Peasant does beat the native mod operand, especially the inline  assembly code version.

However, in C# you be hard pressed to beat the native implementation.
 


using System;
using System.Diagnostics; 
     
public class Program
{
 public static int ModuloBitShiftRussianPeasant(int i, int j)
    {
  if (i <= j) //trivial modulo
   return (i == j) ? 0 : i;
  else if (j==0)
   return i;

  int x = j;
  int halfi = i >> 1;
  while (x < halfi)
  {
   x <<= 1;
  }
  while (i >= j)
  {
   if (i >= x)
    i -= x;
   else
    x >>= 1;
  }
  return i;
 }
 
 public static int ModuloDecimalMath(int i, int j)
    {
  if (i <= j) //trivial modulo
   return (i == j) ? 0 : i;
  else if (j==0)
   return i;
  
  decimal decresult = i/(decimal)j; 
  //Console.WriteLine("decresult="+decresult.ToString());
  //Console.WriteLine("denominator="+(decresult - (int)decresult ).ToString()); 
  //Console.WriteLine("modulo="+((decresult - (int)decresult)*j).ToString()); 
  //modulo=3.999999999999999999999999997 issue! 
             
  //decimal modulo = (decresult - (int)decresult)*j;   
  
  return (int)(((decresult - (int)decresult)*j)+0.000000000000000000000000003M); //add correction
 }
 
 public static int ModuloMathString(int i, int j)
    {
  if (i <= j) //trivial modulo
   return (i == j) ? 0 : i;
  else if (j==0)
   return i;
  
  string decresult = (i/(decimal)j).ToString();
  int idxperiod = decresult.IndexOf('.'); 
  if (idxperiod > -1 )
  {
   string denominator = decresult.Substring(idxperiod); 
   //Console.WriteLine("denominator="+Convert.ToDecimal(denominator).ToString());     
   i = (int)(j*(Convert.ToDecimal(denominator)+0.000000000000000000000000003M)); 
  }
  else 
   i = Convert.ToInt32(decresult); 
 
  return i;
 }
 
 public static int ModuloMathAdditive(int i, int j)
    {
  if (i <= j) //trivial modulo
   return (i == j) ? 0 : i;
  else if (j==0)
   return i;
    
       int total = 0;
       int y = 0;
  
  for (int x = 0; x < i; x++)
  {
   //Console.WriteLine("y {0} > {1} ",y,  (j - 1));
   if (y > (j - 1))
   {
    total += y;
    y = 0;
       //Console.WriteLine("x={0} total={1}",y, total);
   }
   y += 1;
   
   if ((total + y) >= i) return y;  
   
  }
       
  return total;
  
 }
 
 public static void Main()
 {
  int number = 123; 
  int div = 7; 
  int mod = 0; 
  Stopwatch sw = new Stopwatch(); 
  sw.Start(); 
  mod = number % div; 
  sw.Stop();
  
  Console.WriteLine("{0} % {1} mod={2}",number,div,mod);
  Console.WriteLine(sw.ElapsedTicks+" ticks");
  
  sw.Reset();
  sw.Start(); 
  mod = ModuloBitShiftRussianPeasant(number, div); 
  sw.Stop();
  
  Console.WriteLine("ModuloBitShiftRussianPeasant mod="+mod);
  Console.WriteLine(sw.ElapsedTicks+" ticks");
  
  
  sw.Reset();
  sw.Start(); 
  mod = ModuloDecimalMath(number, div); 
  sw.Stop();
  
  Console.WriteLine("ModuloDecimalMath mod="+mod);
  Console.WriteLine(sw.ElapsedTicks+" ticks");
  
  sw.Reset();
  sw.Start(); 
  mod = ModuloMathString(number, div); 
  sw.Stop();
  
  Console.WriteLine("ModuloMathString mod="+mod);
  Console.WriteLine(sw.ElapsedTicks+" ticks");
  
  sw.Reset();
  sw.Start(); 
  mod = ModuloMathAdditive(number, div); 
  sw.Stop();
  
  Console.WriteLine("ModuloMathAddative mod="+mod);
  Console.WriteLine(sw.ElapsedTicks+" ticks");
  
  
  
 }
}