rt.最近在看编码方面的文章,了解到 utf32 是定长编码,String.charAt 方法对此编码有更好的支持,于是写了段代码试了一下:
long start = System.nanoTime();
for (int i = 0; i < utf8.length(); i++) {
char c = utf8.charAt(i);
}
long end = System.nanoTime();
System.out.println(end - start);
start = System.nanoTime();
for (int i = 0; i < utf32.length(); i++) {
char c = utf32.charAt(i);
}
end = System.nanoTime();
System.out.println(end - start);
System.out.println("==========");
将这段代码放入 for 循环中输出如下
5435600
3786200
==========
5370700
200
==========
....
手动复制代码片段执行输出如下:
7608200
5690900
==========
5709800
4930700
==========
...
放入 for 循环中执行的代码,从第二次循环开始 utf32 耗时在 0-500 纳秒浮动 是代码哪里写的有问题吗? utf8 和 utf32 两个 String 对象是同一段一亿个字符的文本
1
Kasumi20 2022-02-11 15:28:47 +08:00 1
你的 utf8 和 utf32 怎么来的?这样 new 出来的吗?
String(byte[] bytes, Charset charset) Constructs a new String by decoding the specified array of bytes using the specified charset. Java 中的对象使用无法修改的 UTF-16 编码,不可能有 UTF-8 和 UTF-32 编码的 Java 字符串。 |
2
txwd 2022-02-11 16:10:00 +08:00
借楼问,为什么 Java 的工程目录要那么多层级...\src\main\java\com\...
|
3
KomiSans 2022-02-11 16:11:46 +08:00
[![HadMz8.png]( https://s4.ax1x.com/2022/02/11/HadMz8.png)]( https://imgtu.com/i/HadMz8)
像是这样的么? 好像对于比较大的文本 UTF32 耗时比较短相对于 UTF8 |
4
q474818917 2022-02-11 16:27:01 +08:00 1
还学 java ?这都卷成什么样了
|
5
chur OP @Kasumi20 貌似是可以的?对同一个字符的 byte 数组使用 new String 指定 utf-8 或 utf-32 字符集重新编码会得到不同的结果
|
7
chur OP @txwd src/main/java 貌似是 maven 编译项目时默认的路径,可以修改; com 和后面的就是自定义的了
|
8
VeryZero 2022-02-11 16:49:15 +08:00
感觉是被优化了,把各种优化关了试试
|
9
xiangyuecn 2022-02-11 16:50:12 +08:00 2
@txwd #2 java 没有要求你这样搞,但开发环境要求你这样搞😂 其实你源码随便放哪里都行,只要编译时找得到😂
|
10
xiangyuecn 2022-02-11 16:53:21 +08:00
欢迎观摩我手撸的 java 仓库,https://github.com/xiangyuecn/RSA-java 源码文件全丢在根目录,但包名还是那个包名🐶
|
11
gadfly3173 2022-02-11 17:03:34 +08:00 1
@txwd #2 这玩意算是工程实践,src 下 main 放项目源码,test 放单元测试; main 下 java 放包名路径,resource 下放要打包进去的资源。你乐意的话把打包配置改了也能放别的地方
|
12
Jooooooooo 2022-02-11 17:17:13 +08:00
搜 jit
|
13
Kasumi20 2022-02-11 17:25:18 +08:00
charset 不是指定 String 的编码,而是指定 bytes 的解码方法,你用 UTF-32 去解码,得到的乱码字符数量很可能只是 UTF-8 的四分之一
|
14
Kasumi20 2022-02-11 17:32:05 +08:00
如果你这堆文本都是 UTF-8 编码的汉字的话,UTF-8 和 UTF-32 去解码得到的 UTF-16 代码点的比值应该是 3 : 4 ,即 0.75
> 4930700/5709800 0.8635503870538372 > 5690900/7608200 0.7479955837123105 似乎是成立的 |
15
thedrwu 2022-02-11 17:35:10 +08:00 via Android 2
@txwd
可能因为 Java 语言的设计初衷就不是用来写单文件的迷你 script 的。于是人们在 applet 之外发明了 javascript 。 讽刺的是 javascript 屠了 applet 的龙。 |
16
pxiphx891 2022-02-11 18:10:03 +08:00
|
17
pxiphx891 2022-02-11 18:11:50 +08:00
可以试试这段代码:
```java import java.nio.charset.StandardCharsets; public class Utf{ public static void main(String[] args) throws Exception { for (int j = 0; j < 30; j++) { String b = "《新能源汽车推广应用推荐车型目录》( 2021 年第 4 批)车型主要参数"; String utf8 = new String(b.getBytes(),StandardCharsets.UTF_8); String utf32 = new String(b.getBytes(), "UTF_32"); long start = System.nanoTime(); for (int i = 0; i < utf8.length(); i++) { char c = utf8.charAt(i); System.out.printf("%s",c); } System.out.printf("%n"); long end = System.nanoTime(); System.out.println(end - start); start = System.nanoTime(); for (int i = 0; i < utf32.length(); i++) { char c = utf32.charAt(i); System.out.printf("%s",c); } System.out.printf("%n"); end = System.nanoTime(); System.out.println(end - start); System.out.println("=========="); } } } ``` 结果是这样的: ``` 《新能源汽车推广应用推荐车型目录》( 2021 年第 4 批)车型主要参数 358397 ����������������������� 255780 ========== 《新能源汽车推广应用推荐车型目录》( 2021 年第 4 批)车型主要参数 415140 ����������������������� 226139 ========== ``` |
18
maokabc 2022-02-11 21:24:06 +08:00 via Android
你测试 utf8 不用 byte 数组,utf32 不用 int 数组,用 String 干什么? String 固定的 utf16 没其他编码。
|
19
ohwind 2022-02-11 21:41:12 +08:00
|
21
bequt 2022-02-11 22:41:21 +08:00
已经开始学,rust 了
|
22
EscYezi 2022-02-13 04:26:09 +08:00 via iPhone
@txwd #2 src/main/java 是 maven 项目约定的源码位置,后面的 com/…是因为 java 包名通常是域名倒序,如 api.baidu.com 变成 com/baidu/api
|
23
Bingchunmoli 2022-02-13 12:34:12 +08:00
@txwd 你看一看现在前端也是 src public 什么的,都是规范的事情,你可以用,但是约定大于配置,都用规范,易懂,好用
|
24
chur OP @maokabc 没太明白你的意思。String 如果没有显示指定字符集,默认是按系统默认字符集来的? java 内部存储字符使用的是 utf-16 编码,实际调用 getBytes 等方法时会有一个转码的过程
|