Mapreduce中的字符串编码
Mapreduce中的字符串编码
$$$
Shuffle的执行过程,需要经过多次比较排序。如果对每一个数据的比较都需要先反序列化,对性能影响极大。 RawComparator的作用就不言而喻,能够直接使用序列化后的字节流进行比较,不需要反序列化就能够完成排序功能。
$$$
hadoop使用的是jdk自带编码器和解码器(DataOutputStream和DataInputStream),它有一套规则把字符转化成字节。1个字符可能转化成1个,2个或者3个字节。
字节流开始处用2个字节,写了字节流的有效长度,它的字节流最长是65535 (这个长度是编码后的字节流长度,不是传进行的字符串长度)
在RawComparator读到的,是在这种规则下转换后的字节流,不能够直接使用它来做比较了。。。在 二次排序 里面我用了一种变通的方法解决这个问题。最好的方法是模仿Text的编码和比较器的实现,然后实现自定义key的比较器
在这里主要是解析一下,Why???
DataOutputStream.writeUTF()的源码不长,直接上
/**
** 把字符串编码为utf字节流,并写进out
**/
static int writeUTF(String str, DataOutput out) throws IOException {
int strlen = str.length();
int utflen = 0;
int c, count = 0;
/* 计算编码后的字节流长度 */
for (int i = 0; i < strlen; i++) {
c = str.charAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) { // ascii字符,1个字符->1个字节
utflen++;
} else if (c > 0x07FF) { // 1个字符->3个字节
utflen += 3;
} else {
utflen += 2; // 1个字符->2个字节
}
}
// 编码后的字节流总长度不能超过65535
if (utflen > 65535)
throw new UTFDataFormatException(
"encoded string too long: " + utflen + " bytes");
// 初始化用于编码的缓冲区
byte[] bytearr = null;
if (out instanceof DataOutputStream) {
DataOutputStream dos = (DataOutputStream)out;
if(dos.bytearr == null || (dos.bytearr.length < (utflen+2)))
dos.bytearr = new byte[(utflen*2) + 2];
bytearr = dos.bytearr;
} else {
bytearr = new byte[utflen+2];
}
// 开头的2个字节,写字符串长度 utflen
bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
// 先写入 [1到7E]的字符, 即ascii字符, 1个字符->1个字节
int i=0;
for (i=0; i<strlen; i++) {
c = str.charAt(i);
if (!((c >= 0x0001) && (c <= 0x007F))) break;
bytearr[count++] = (byte) c;
}
for (;i < strlen; i++){
c = str.charAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) { // ascii字符
bytearr[count++] = (byte) c;
} else if (c > 0x07FF) { // 非ascii字符,需要3个字节
bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
} else {
bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); // 其余的非ascii字符,需要2个字节
bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
}
}
out.write(bytearr, 0, utflen+2);
return utflen + 2;
}
Mapreduce中的字符串编码的更多相关文章
- 使用自己的Python函数处理Protobuf中的字符串编码
我目前所在的项目是一个老项目,里面的字符串编码有点乱,数据库中有些是GB2312,有些是UTF8:代码中有些是GBK,有些是UTF8,代码中转来转去,经常是不太清楚当前这个字符串是什么编码,由于是老项 ...
- 关于python中的字符串编码理解
python2.x 中中间编码为unicode,一个字符串需要decode为unicode,再encode为其它编码格式(gbk.utf8等) 以gbk转utf8为例: s = "我是字符串 ...
- javascript中的字符串编码、字符串方法详解
js中的字符串是一种类数组,采用UTF-16编码的Unicode字符集,意味字符串的每个字符可用下标方式获取,而每个字符串在内存中都是一个16位值组成的序列.js对字符串的各项操作均是在对16位值进行 ...
- Python2和Python3中的字符串编码问题解决
Python2和Python3在字符串编码上是有明显的区别. 在Python2中,字符串无法完全地支持国际字符集和Unicode编码.为了解决这种限制,Python2对Unicode数据使用了单独的字 ...
- python中的字符串编码问题——1.理解编码和解码问题
理解编码与解码(python2.7):1)编码 是根据一个想要的编码名称,把一个字符串翻译为其原始字节形式.>>> u_str=u'字符串编码aabbbcccddd'>> ...
- JavaScript中有对字符串编码的三个函数:escape,encodeURI,encodeURIComponent
JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decod ...
- Python3中转换字符串编码
在使用subprocess调用Windows命令时,遇到了字符串不显示中文的问题,源码如下:#-*-coding:utf-8-*-__author__ = '$USER' #-*-coding:utf ...
- Code::Blocks开发中的字符串编码错误
刚开始使用Code::Blocks开发Windows中文应用程序的朋友们,如果在代码中使用了中文字符串,编译时可能遇到过Illegal byte sequence或Failure to convert ...
- python中的字符串编码问题——4.unicode编解码(以实际工作中遇到的韩文编码为例)
韩文unicode编解码 问题是这样,工作中遇到有韩文数据出现乱码,说是unicode码. 类似这样: id name 323 52186863 149 63637538 314 65516863 ...
随机推荐
- Java中1000==1000为false而100==100为true
public static void main(String[] args) { int z1 = 0; int z2 = 0; System.out.println(z1==z2);//TRUE I ...
- android 隐藏系统键盘
-----------------------------------------已验证----------------------------------- public static void c ...
- 使用Spring的Property文件存储测试数据 - 编写测试和调用测试数据
准备好测试数据后,我们可以开始编写测试了,在测试用例中调用我们property文件中的测试数据. 我自己写了一个TestCase作为所有测试类基类,基类中定义了两个变量来代表之前建好的两个测试数据文件 ...
- Ant 脚本打印系统属性变量、ant内置属性
Ant 脚本打印系统属性变量.ant内置属性 作用 编写ant脚本的时候,经常会引用到系统属性,本脚本用于打印系统常用属性(System.getProperties)与环境变量(Environment ...
- Unity项目在亚马逊KindleFire设备上旋转不正确的解决方案
前提: 在亚马逊设备上,总部要求发布的版本必须使用LandscapeLeft方向.按照经验,在UnityPlayerSettings中设置Orientation即可. 问题表现: ...
- [原创]大连sap vt 实习生面试经历
从决定参加这次面试开始,求职生涯就算是开始了,虽然失败了,但也是亲身体会到了面试的感觉,这次经历也作为第一篇博客. 大连sap的职能是sap的全球技术支持中心和解决方案提供中心.VT项目提供的岗位是技 ...
- 基于OpenDaylight和Mininet的试验床平台搭建
##########################################平台架构######################################### 一.虚拟机安装和镜像加载 ...
- AceAdmin In MVC之控件
AceAdmin有很多Html控件,而下载下来之后全部混杂在一起,想用一个控件有时得调整半天,干脆整理出一个版本,而且结合起来MVC的封装.以后就不用一个js css的调了. 在MVC中Html的控件 ...
- 原创: EasyUI Tree 最后一级 节点 横向排列
原创: EasyUI Tree 最后一级 节点 横向排列 转载请指明出处 必须要写在: onLoadSuccess 事件中 ddAuthTree.tree({ lines: true, checkb ...
- vim中查找指定字符串
0x01 自当前光标位置向上搜索 /pattern Enter (pattern表示要搜索的字符串) 0x02 自当前光标位置向下搜索 ?pattern Enter 0x03 n继续从同 ...