改善一下Int.Parse的性能

本文介绍了一种自定义的字符串转整数方法,通过避免使用取幂运算和选择更高效的循环结构,实现了比标准Int.Parse方法更快的速度。文中提供了两种实现方案,并详细对比了它们之间的性能差异。

  偶尔吹毛求疵一下,众所周知,各种数值类型的Parse方法是很耗时间的。比如定义一个string s = "123",int n = 123,我们看s到n之间,没有任何理解障碍。但计算机就不行,它要一堆转换才能明白s到n的关系。下面写了一个自定义的类型转换函数。

 

  没有用Math.Pow函数求幂,速度提高了两倍;将自定义求幂函数与主函数合并一起,速度快了近一倍;使用while而不是for循环,速度略有提高。如果加上转换失败处理,总体速度大约比Int.Parse快一倍。

 

Code
        static int ParseInt(string s)
        {
            
int L = s.Length - 1int n = 0, result = 0;
            
while (L >= 0)
            {
                
int x = 1, y = n;
                
while (y > 0)
                {
                    x 
= x * 10;
                    y
--;
                }
                result 
+= (s[L] - 48* x;
                n
++;
                L
--;
            }
            
return result;
        }

 

  但是,要将速度提高一个数量级,找不到思路了。又仔细想了一下,其实完全不用取幂的。

 

Code
        static int ParseInt(string s)
        {
            
int L = s.Length - 1int n = 1, result = 0;
            
while (L >= 0)
            {
                
int c = s[L] - 48;
                
if (c > 9 || c < 0throw new InvalidCastException();
                result 
+= c * n;
                n 
*= 10;
                L
--;
            }
            
return result;
        }

 

  这样速度又提高了近20%,看来传统方式潜力不大了,不知道是不是应该从指针直接操作内存入手呢?

 

我用的是Easymodbus的包哦,5.6.0版本的。声明我是这样写的// 声明静态数组 static ModbusClient[] modbusArray = new ModbusClient[100]; // 创建长度为5的数组 // 声明线程数组 private Thread[] modbusThreads = new Thread[100]; // 创建100个线程的数组 // 声明取消线程标记数组 private volatile bool[] threadStopRequests = new bool[100]; // 声明StringBuilder数组 private StringBuilder[] M_receivedDataBuffers = new StringBuilder[100]; 这是连接设备和打开线程的: private void PLC_Connectivity(int ArrayNumber, string CommProtocol, string IPaddress, string Port, string COM, string Baudrate, string Parity_str, string IDnum) { if (CommProtocol == "modbus_TCP") { if (connStateBools[ArrayNumber] == false) { try { modbusArray[ArrayNumber] = new ModbusClient(); modbusArray[ArrayNumber].Connect(IPaddress, Convert.ToInt16(Port)); M_receivedDataBuffers[ArrayNumber] = new StringBuilder(); threadStopRequests[ArrayNumber] = false; // 重置停止标志 modbusThreads[ArrayNumber] = new Thread(() => ModbusThreadMethod(ArrayNumber)); modbusThreads[ArrayNumber].IsBackground = true; modbusThreads[ArrayNumber].Start(); connStateBools[ArrayNumber] = true; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } else if (CommProtocol == "modbus_RTU") { if (connStateBools[ArrayNumber] == false) { try { modbusArray[ArrayNumber] = new ModbusClient(COM); modbusArray[ArrayNumber].UnitIdentifier = byte.Parse(IDnum);//从站ID modbusArray[ArrayNumber].Baudrate = int.Parse(Baudrate); // 获取选择的波特率 modbusArray[ArrayNumber].StopBits = StopBits.One;//停止位 modbusArray[ArrayNumber].ConnectionTimeout = 1000;//连接超时 //校验位 if (Parity_str == "None") { modbusArray[ArrayNumber].Parity = Parity.None; } else if (Parity_str == "Odd") { modbusArray[ArrayNumber].Parity = Parity.Odd; } else if (Parity_str == "Even") { modbusArray[ArrayNumber].Parity = Parity.Even; } modbusArray[ArrayNumber].Connect();//modbus连接 M_receivedDataBuffers[ArrayNumber] = new StringBuilder(); threadStopRequests[ArrayNumber] = false; // 重置停止标志 modbusThreads[ArrayNumber] = new Thread(() => ModbusThreadMethod(ArrayNumber)); modbusThreads[ArrayNumber].IsBackground = true; modbusThreads[ArrayNumber].Start(); connStateBools[ArrayNumber] = true; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } } 这个是关闭线程的: public void StopModbusThread(int arrayNumber) { if (modbusThreads[arrayNumber] != null && modbusThreads[arrayNumber].IsAlive) { // 1. 设置停止标志 threadStopRequests[arrayNumber] = true; // 2. 等待线程完成当前周期(最多等待500ms) if (!modbusThreads[arrayNumber].Join(1000)) { // 3. 如果超时仍未停止,尝试中断(比Abort更安全) modbusThreads[arrayNumber].Interrupt(); } // 4. 重置线程对象 modbusThreads[arrayNumber] = null; } } 可以再帮我整合一下吗,因为第一次接触多线程真的难理解
最新发布
08-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值