在我多年的开发经验中,经常发现的一个情况就是,很多项目的对象字段或者是数据库字段本来是数字类型的,却被定义成字符串类型,这无关痛痒吗?
对于小项目来说,可能没什么影响,反正只要业务逻辑正确即可,性能没什么问题,因为数据也不多,用户也不多。
然而,对于大数据处理来说,这个可不是小事,从字符串替换为数字类型,可以极大地节省内存、磁盘存储以及网络带宽,减少IO的代价,而且很多数据结构和算法使用数字类型比字符串要更快。
我们来看一个例子,假设你有很多的日志需要处理,而每条日志都有一个唯一的标识,标识类似这样的格式:
F5051582611729507844 3832154813577306424 F1624235934976711017 3810376634214027595 F6884923813121317381 7278044081826528150
看到这些标识,你怎么想?我的第一反应应该是数字,可是怎么有个F呢?我想可以把它当做16进制。后来发现可以把F当做负号,这就是一个64位的长整型。
那么如果你把这些标识当成字符串,会有什么不同呢?
当然有,如果你每秒要处理这样的日志百万或者千万条,每条处理结果可能会包含百万或者千万个这样的标识元素构成的集合,这个不同就会体现的非常明显。
下面,我们来分析一下标识3832154813577306424的存储占用情况:
1、内存占用
当做字符串:我们知道,JAVA中字符串是由字符构成的,一个字符是由2个字节构成的(这是JAVA的悲剧了),上述标识有19个字符,所以,占用的内存大小为:19*2+4=42(字节),+4是因为字符串使用一个整型保存字符串的哈希值。
当做数字:如当做长整型,则占用的内存大小为8字节。
这里有5倍以上的差距了吧。
2、序列化字节大小
当我们需要通过网络传输这些标识或者需要把这些标识存储到磁盘中的时候,我们就需要把这些标识转换为字节数组,如何转换为字节数组呢?我们可以使用多种编码方式。
当做字符串:我们知道,JAVA中字符串转换为字节数组可以使用多种编码方式,我们看看常见的编码方式对如上字符串编码之后的字节数:
String abc = "3832154813577306424"; System.out.println("3832154813577306424 length:"+abc.length()); System.out.println(Charset.defaultCharset().name()+":"+abc.getBytes().length); System.out.println("unicode:"+abc.getBytes("unicode").length); System.out.println("gbk:"+abc.getBytes("gbk").length); System.out.println("gb2312:"+abc.getBytes("gb2312").length); System.out.println("ISO-8859-1:"+abc.getBytes("ISO-8859-1").length);
输出如下:
3832154813577306424 length:19 UTF-8:19 unicode:40 gbk:19 gb2312:19 ISO-8859-1:19
当做数字:如当做长整型,则占用的内存大小为8字节。
这里有2倍以上的差距了吧。
那么我们如何在长整型和字节数组之间转换呢?
String abc = "3832154813577306424"; System.out.println("3832154813577306424 length:"+abc.length()); System.out.println("long:"+ByteUtils.longToBytes(Long.parseLong(abc)).length); byte[] bytes = ByteUtils.longToBytes(Long.parseLong(abc)); System.out.println("string:"+ByteUtils.bytesToLong(bytes));
输出如下:
3832154813577306424 length:19 long:8 string:3832154813577306424
ByteUtils代码如下:
public static byte[] longToBytes(long x) { ByteBuffer longBuffer = ByteBuffer.allocate(Long.BYTES); longBuffer.putLong(0, x); return longBuffer.array(); } public static long bytesToLong(byte[] bytes) { return bytesToLong(bytes, 0, bytes.length); } public static long bytesToLong(byte[] bytes, int offset, int length) { ByteBuffer longBuffer = ByteBuffer.allocate(Long.BYTES); longBuffer.put(bytes, offset, length); longBuffer.flip();//need flip return longBuffer.getLong(); }
(本文摘自http://yangshangchuan.iteye.com/blog/2239571)
相关推荐
例如,在数据校验、格式化输出或者解析特定格式的数据时,可能需要找出字符串中数字的位置。本篇文章将详细介绍如何在C#中实现这一功能。 #### 解决方案概述 为了实现上述需求,我们需要完成以下步骤: 1. **读取...
若要保证字符分布更均匀,可以使用更复杂的随机数生成算法,或者对生成的字符串进行一定的调整。 总的来说,生成随机字符串和数字在C#编程中是一项基础且实用的技能。通过掌握`Random`类的使用和字符串操作,你可以...
创建一个`DecimalFormat`实例后,我们可以使用`format()`方法将数字转换为字符串。 下面是一个简单的示例,展示了如何使用`DecimalFormat`设置千分位分隔: ```java import java.text.DecimalFormat; public ...
### 统计字符串中数字的个数 #### 实验内容 本实验的主要目的是设计并实现一个程序,用于统计一个特定字符串中所有数字的出现次数,并按照数字从小到大的顺序输出这些数字及其出现次数。 #### 输入格式 - **Input...
以上就是使用Delphi实现数字和字母组合的字符串数字部分不断自加的具体方法。在实际应用中,你可能需要根据具体需求调整代码,例如处理不同长度的数字部分,或者支持其他类型的自增逻辑。这个过程涉及到字符串操作、...
- 对于效率,可能需要考虑优化算法,比如预计算进制幂表,避免重复计算,或者使用更高效的字符串处理方法。 7. **内存管理与安全性**: - 确保在处理字符串时避免内存泄漏,使用智能指针或其他内存管理策略。 - ...
在本例中,我们使用了正则表达式 `[0-9]*` 来判断一个字符串是否只由数字组成。这里的关键点包括: - **`[0-9]`**:表示从0到9的任意单个数字。 - **`*`**:表示前面的模式可以出现零次或多次。 因此,`[0-9]*` ...
但是,开发者通常会使用类似的方法来编写这样的函数,确保输入的字符串符合JSON的语法规则,从而在C语言项目中正确地处理JSON数据。对于大型项目,可能会选择成熟的C JSON库,如cJSON或Jansson,它们提供了完整的...
1. **内置函数**:在某些SQL方言中,如MySQL,你可以使用`STR_TO_DATE()`函数或`CAST()`/`CONVERT()`函数来尝试将字符串转换为数字。但这些函数并不能直接处理算术表达式,只能用于简单的数字字符串转换。 2. **...
在这种情况下,你可以使用`ToString()`方法配合标准格式说明来确保字符串格式正确。 例如,如果你需要将一个`double`类型的数值写入到数据库的`DECIMAL(10,2)`字段,可以使用`"F2"`格式: ```csharp double ...
该问题要求使用给定的数字字符串,构建一个能够整除15的最大整数,注意每个字符只能使用一次。下面是对该问题的详细解析和解决方案。 问题描述: 给定一个只包含数字[0…9]的字符串,请使用字符中的某些字符,构建...
其中,`input`是要读取的数据源,可以是字符串或者字符数组;`formatSpec`定义了数据的格式,比如数值类型、精度等;`output`是读取到的数据,会根据`formatSpec`的定义返回相应类型的变量;`maxNumChars`可选,用于...
通常,如果你需要将整型数字转换为十六进制字符串,可以使用内置的 `CONVERT` 函数配合 `style` 参数。例如,如果你有一个整数变量 `@myInt`,你可以使用以下语句将其转换为十六进制: ```sql SELECT CONVERT...
在使用“VAL”函数时,需要确保字符串格式正确,否则可能引发错误。 ```scl VAR strValue : STRING; // 输入字符串 realValue : REAL; // 转换后的实数 END_VAR realValue := VAL(strValue); // 调用VAL函数进行...
我们可以使用正则表达式来分割字符串,提取数字和操作符。 2. **表达式树(Expression Tree)**:为了正确处理运算符的优先级,我们通常会构建一个表达式树。每个节点代表一个操作或者一个数字,而边表示操作的执行...
5. **输出格式化**:使用 `ADD DL, 30H` 将数字转换成ASCII码以便正确输出。 #### 五、总结 本程序通过简单的汇编语言指令实现了两个字符串的匹配查找,并且能够统计出匹配的数量。虽然程序较为基础,但它展示了...
1. **分词**:使用`Split`方法按运算符(如"+","-"等)拆分字符串,得到包含数字和变量的字符串数组。 2. **变量解析**:识别出代表数值的变量(如“基本工资”和“奖金”),这可能需要查找预先定义的字典或者从...
在进行字符串查找替换时,需要注意一些事项,如备份原始文件以防万一,理解并正确使用正则表达式,以及合理设置查找范围和匹配条件。对于大型项目,理解查找替换的效率和可能影响也是必要的,因为不当操作可能导致...
ABB机器人在RobotStudio中进行数字与字符串相互转换是编程中常见的操作,特别是在处理用户输入或者进行数据处理时。本文将详细讲解如何在RobotStudio中利用Rapid语言进行这些转换。 首先,我们需要打开ABB的...
4. **显示在QLineEdit**:最后,使用QLineEdit的`setText()`方法将转换后的16进制字符串设置为其显示内容。例如,`lineEdit->setText(hexString)`。 为了确保显示的可靠性,你可能还需要考虑以下几点: - **错误...