String을 사용하는 것이 더 좋은 습관인가?문자열 위에 형식 자바에서 연결하시겠습니까?
사용 사이에 감지할 수 있는 차이가 있는가?String.format
자바에서 끈 연결은?
나는 사용하는 경향이 있다.String.format
하지만 가끔 미끄러져서 연결 장치를 사용하기도 하고한쪽이 다른 쪽보다 나은지 궁금했다.
내가 보기엔String.format
연결은 실수로 %s을(를) 더 넣거나 빼내는 것에 대해 걱정할 필요가 없다는 것을 의미한다.
String.format
또한 더 짧다.
어느 것이 더 읽기 쉬운지는 당신의 머리가 어떻게 작동하느냐에 달려 있다.
나는 그것을 사용하는 것이 더 낫다고 제안하고 싶다.String.format()
큰 String.format()
리소스 파일에서 로드된 텍스트로 보다 쉽게 로컬화할 수 있는 반면, 각 언어에 대해 서로 다른 코드를 가진 새로운 실행 파일을 생성하지 않고는 로컬로 연결될 수 없다.
앱이 로컬로 실행될 수 있도록 계획하는 경우 형식 토큰에 대한 인수 위치도 지정하는 습관을 들여야 한다.
"Hello %1$s the time is %2$t"
그런 다음, 다른 순서를 설명하기 위해 실행 파일의 재구성 없이 이름과 시간 토큰을 교환할 수 있다.또한 인수 위치를 사용하여 동일한 인수를 함수에 두 번 전달하지 않고 다시 사용할 수 있다.
String.format("Hello %1$s, your name is %1$s and the time is %2$t", name, time)
성능 정보:
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
for(int i = 0; i < 1000000; i++){
String s = "Hi " + i + "; Hi to you " + i*2;
}
long end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond") ;
start = System.currentTimeMillis();
for(int i = 0; i < 1000000; i++){
String s = String.format("Hi %s; Hi to you %s",i, + i*2);
}
end = System.currentTimeMillis();
System.out.println("Format = " + ((end - start)) + " millisecond");
}
타이밍 결과는 다음과 같다.
- 연결 = 265밀리초
- 형식 = 4141밀리초
그러므로 결합은 스트링보다 훨씬 빠르다.형식을 갖추다
에 대한 한가지 문제.format
정전식 안전장치를 잃어버리는 겁니다형식에 대해 인수를 너무 적게 가질 수 있으며 형식 지정자에 대해 잘못된 유형을 가질 수 있음 - 둘 다로 인해IllegalFormatException
런타임에 생산을 중단하는 로그 코드로 끝날 수 있다.
이와는 대조적으로, 다음과 같은 인수는+
컴파일러에 의해 테스트될 수 있다.
printf의 보안 기록(이력에서 다음 항목이 포함됨)format
기능이 모델링됨)은 길고 무섭다.
성능에 대한 논의가 있기 때문에 StringBuilder를 포함한 비교에 추가해야겠다고 생각했다.그것은 사실 콩코트보다 더 빠르고 자연스럽게 스트링이다.포맷 옵션
이것을 사과와 사과 비교의 일종으로 만들기 위해 나는 바깥쪽이 아닌 루프에서 새로운 StringBuilder를 인스턴스화한다(실제로 이것은 한 빌더 끝에서 루프 추가에 대한 공간을 재할당하는 오버헤드 때문에 가장 가능성이 높은 하나의 인스턴스화만 수행하는 것보다 빠르다).
String formatString = "Hi %s; Hi to you %s";
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format(formatString, i, +i * 2);
}
long end = System.currentTimeMillis();
log.info("Format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "Hi " + i + "; Hi to you " + i * 2;
}
end = System.currentTimeMillis();
log.info("Concatenation = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
StringBuilder bldString = new StringBuilder("Hi ");
bldString.append(i).append("; Hi to you ").append(i * 2);
}
end = System.currentTimeMillis();
log.info("String Builder = " + ((end - start)) + " millisecond");
- 2012-01-11 16:30:46,058 정보 [TestMain] - 형식 = 1416밀리초
- 2012-01-11 16:30:46,190 정보 [TestMain] - 연결 = 134밀리초
- 2012-01-11 16:30:46,313 정보 [TestMain] - String Builder = 117밀리초
어느 것이 더 읽기 쉬운지는 당신의 머리가 어떻게 작동하느냐에 달려 있다.
바로 거기에 답이 있어.
개인적인 취향의 문제다.
끈 연결은 조금 더 빠르긴 하지만 그건 무시해도 될 거야.
밀리초 단위의 여러 표본 크기를 가진 테스트가 여기에 있다.
public class Time {
public static String sysFile = "/sys/class/camera/rear/rear_flash";
public static String cmdString = "echo %s > " + sysFile;
public static void main(String[] args) {
int i = 1;
for(int run=1; run <= 12; run++){
for(int test =1; test <= 2 ; test++){
System.out.println(
String.format("\nTEST: %s, RUN: %s, Iterations: %s",run,test,i));
test(run, i);
}
System.out.println("\n____________________________");
i = i*3;
}
}
public static void test(int run, int iterations){
long start = System.nanoTime();
for( int i=0;i<iterations; i++){
String s = "echo " + i + " > "+ sysFile;
}
long t = System.nanoTime() - start;
String r = String.format(" %-13s =%10d %s", "Concatenation",t,"nanosecond");
System.out.println(r) ;
start = System.nanoTime();
for( int i=0;i<iterations; i++){
String s = String.format(cmdString, i);
}
t = System.nanoTime() - start;
r = String.format(" %-13s =%10d %s", "Format",t,"nanosecond");
System.out.println(r);
start = System.nanoTime();
for( int i=0;i<iterations; i++){
StringBuilder b = new StringBuilder("echo ");
b.append(i).append(" > ").append(sysFile);
String s = b.toString();
}
t = System.nanoTime() - start;
r = String.format(" %-13s =%10d %s", "StringBuilder",t,"nanosecond");
System.out.println(r);
}
}
TEST: 1, RUN: 1, Iterations: 1
Concatenation = 14911 nanosecond
Format = 45026 nanosecond
StringBuilder = 3509 nanosecond
TEST: 1, RUN: 2, Iterations: 1
Concatenation = 3509 nanosecond
Format = 38594 nanosecond
StringBuilder = 3509 nanosecond
____________________________
TEST: 2, RUN: 1, Iterations: 3
Concatenation = 8479 nanosecond
Format = 94438 nanosecond
StringBuilder = 5263 nanosecond
TEST: 2, RUN: 2, Iterations: 3
Concatenation = 4970 nanosecond
Format = 92976 nanosecond
StringBuilder = 5848 nanosecond
____________________________
TEST: 3, RUN: 1, Iterations: 9
Concatenation = 11403 nanosecond
Format = 287115 nanosecond
StringBuilder = 14326 nanosecond
TEST: 3, RUN: 2, Iterations: 9
Concatenation = 12280 nanosecond
Format = 209051 nanosecond
StringBuilder = 11818 nanosecond
____________________________
TEST: 5, RUN: 1, Iterations: 81
Concatenation = 54383 nanosecond
Format = 1503113 nanosecond
StringBuilder = 40056 nanosecond
TEST: 5, RUN: 2, Iterations: 81
Concatenation = 44149 nanosecond
Format = 1264241 nanosecond
StringBuilder = 34208 nanosecond
____________________________
TEST: 6, RUN: 1, Iterations: 243
Concatenation = 76018 nanosecond
Format = 3210891 nanosecond
StringBuilder = 76603 nanosecond
TEST: 6, RUN: 2, Iterations: 243
Concatenation = 91222 nanosecond
Format = 2716773 nanosecond
StringBuilder = 73972 nanosecond
____________________________
TEST: 8, RUN: 1, Iterations: 2187
Concatenation = 527450 nanosecond
Format = 10291108 nanosecond
StringBuilder = 885027 nanosecond
TEST: 8, RUN: 2, Iterations: 2187
Concatenation = 526865 nanosecond
Format = 6294307 nanosecond
StringBuilder = 591773 nanosecond
____________________________
TEST: 10, RUN: 1, Iterations: 19683
Concatenation = 4592961 nanosecond
Format = 60114307 nanosecond
StringBuilder = 2129387 nanosecond
TEST: 10, RUN: 2, Iterations: 19683
Concatenation = 1850166 nanosecond
Format = 35940524 nanosecond
StringBuilder = 1885544 nanosecond
____________________________
TEST: 12, RUN: 1, Iterations: 177147
Concatenation = 26847286 nanosecond
Format = 126332877 nanosecond
StringBuilder = 17578914 nanosecond
TEST: 12, RUN: 2, Iterations: 177147
Concatenation = 24405056 nanosecond
Format = 129707207 nanosecond
StringBuilder = 12253840 nanosecond
StringBuilder에서 toString() 메서드를 호출하는 수정과 관련하여 위와 같은 테스트가 있다.아래의 결과는 StringBuilder 접근법이 + 연산자를 사용하는 String connectation보다 약간 느리다는 것을 보여준다.
파일: StringTest.java
class StringTest {
public static void main(String[] args) {
String formatString = "Hi %s; Hi to you %s";
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format(formatString, i, +i * 2);
}
long end = System.currentTimeMillis();
System.out.println("Format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "Hi " + i + "; Hi to you " + i * 2;
}
end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
StringBuilder bldString = new StringBuilder("Hi ");
bldString.append(i).append("Hi to you ").append(i * 2).toString();
}
end = System.currentTimeMillis();
System.out.println("String Builder = " + ((end - start)) + " millisecond");
}
}
Shell 명령어 : (Compile and run StringTest 5회 실행)
> javac StringTest.java
> sh -c "for i in \$(seq 1 5); do echo \"Run \${i}\"; java StringTest; done"
결과:
Run 1
Format = 1290 millisecond
Concatenation = 115 millisecond
String Builder = 130 millisecond
Run 2
Format = 1265 millisecond
Concatenation = 114 millisecond
String Builder = 126 millisecond
Run 3
Format = 1303 millisecond
Concatenation = 114 millisecond
String Builder = 127 millisecond
Run 4
Format = 1297 millisecond
Concatenation = 114 millisecond
String Builder = 127 millisecond
Run 5
Format = 1270 millisecond
Concatenation = 114 millisecond
String Builder = 126 millisecond
String.format()
그냥 끈을 연결시키는 것 이상이야예를 들어, 다음을 사용하여 특정 로케일의 숫자를 표시할 수 있다.String.format()
.
그러나 국지화에 신경 쓰지 않는다면 기능적인 차이는 없다.한 쪽이 다른 쪽보다 빠를 수도 있지만, 대부분의 경우 무시해도 될 것이다.
일반적으로 문자열 연결은 다음보다 선호되어야 한다.String.format
후자의 두 가지 주요 단점은 다음과 같다.
- 로컬 방식으로 빌드할 문자열을 인코딩하지 않는다.
- 그 건축 과정은 끈으로 암호화되어 있다.
1번 점으로 말하자면, 나는 무엇을 이해하는 것이 불가능하다는 것을 의미한다.String.format()
콜은 단일 순차 패스로 하고 있다.한 사람은 인수의 위치를 세면서 형식 문자열과 인수 사이를 왔다 갔다 할 수밖에 없다.짧은 연결에 있어서 이것은 큰 문제가 되지 않는다.그러나 이러한 경우 끈 연결은 장황하지 않다.
점 2에 의하면, 건물 공정의 중요한 부분이 (DSL을 사용하는) 형식 문자열로 인코딩되어 있다는 것을 의미한다.코드를 나타내기 위해 문자열을 사용하는 것은 많은 단점이 있다.그것은 본질적으로 타입 세이프가드가 아니며, 구문 강조, 코드 분석, 최적화 등을 복잡하게 만든다.
물론, 자바 언어의 외부에 있는 도구나 프레임워크를 사용할 때, 새로운 요소들이 작용할 수 있다.
나는 구체적인 벤치마킹은 하지 않았지만, 나는 결합이 더 빠를 수도 있다고 생각한다.끈형식()은 새로운 형식 지정자를 생성하여 16자만 사용할 수 있는 새 StringBuilder를 생성한다.특히 긴 문자열을 포맷할 때 StringBuilder의 크기를 계속 조정해야 하는 경우에는 상당한 오버헤드가 발생한다.
그러나, 결합은 덜 유용하고 읽기 어렵다.언제나 그렇듯이, 어느 것이 더 나은지 코드에 대한 벤치마크를 할 가치가 있다.리소스 번들, 로케일 등이 메모리에 로드되고 코드가 J인 후 서버 앱에서 차이는 무시할 수 있다.ITTED.
아마도 적절한 크기의 StringBuilder(부록 가능)와 Locale으로 자신만의 Formatter를 만들어 포맷할 것이 많은 경우 사용하는 것이 좋을 것이다.
감지할 수 있는 차이가 있을 수 있다.
String.format
꽤 복잡하고 그 아래에서는 규칙적인 표현을 사용하므로, 어디에서나 사용하는 습관을 들이지 말고, 필요한 곳에만 사용해야 한다.
StringBuilder
(여기 누군가가 이미 지적한 바와 같이) 훨씬 더 빠른 순서가 될 것이다.
나는 우리가 함께 갈 수 있다고 생각한다.MessageFormat.format
가독성과 성능 측면 모두를 잘해야 하기 때문에.
나는 위의 대답에서 Icaro가 사용한 것과 같은 프로그램을 사용했고 사용 코드를 추가해서 그것을 강화했다.MessageFormat
성능 수치를 설명하기 위해.
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "Hi " + i + "; Hi to you " + i * 2;
}
long end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format("Hi %s; Hi to you %s", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("Format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = MessageFormat.format("Hi %s; Hi to you %s", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("MessageFormat = " + ((end - start)) + " millisecond");
}
연결 = 69밀리초
형식 = 1435밀리초
메시지 형식 = 200밀리초
업데이트:
SannaLint Report에 따라 Printf 스타일 형식 문자열을 올바르게 사용해야 한다(스퀴드:S3457)
왜냐하면printf-style
형식 문자열은 컴파일러에 의해 검증되지 않고 런타임에 해석되며, 잘못된 문자열이 생성되는 오류를 포함할 수 있다.이 규칙은 정적으로 의 상관관계를 검증한다.printf-style
형식(...) 메서드를 호출할 때 문자열 형식을 그들의 논거로 지정한다.java.util.Formatter
java.lang.String
java.io.PrintStream
MessageFormat
그리고java.io.PrintWriter
계급과 학벌printf(...)
의 방법.java.io.PrintStream
또는java.io.PrintWriter
반
나는 프린트프 스타일을 곱슬브래킷으로 교체하고 아래와 같은 흥미로운 결과를 얻었다.
= = 69밀리초 결
= = 1107밀리초
형식:커리-브래킷 = 416밀리초
= = 215밀리초MessageFormat = 215밀리초
메시지 형식:커리-브래킷 = 2517밀리초
내내 결론:
을 한 스트링글 스트링글은 수 곱슬곱슬한 형식을 사용하면 가독성과 성능의 이점을 얻을 수 있다.
스트링에 익숙해지려면 시간이 조금 걸린다.형식은, 하지만 대부분의 경우 그럴 가치가 있다.NRA의 세계에서는 토큰화된 메시지(로그인 또는 사용자)를 상수 라이브러리(정적 클래스에 해당하는 것을 선호함)에 보관하고 String으로 필요에 따라 호출하는 것이 매우 유용하다.로컬라이징 여부와 상관없이 포맷하십시오.이러한 라이브러리를 연결 방법으로 사용하려고 하는 것은 연결해야 하는 어떤 접근법으로도 읽기, 문제 해결, 교정 및 관리하기 어렵다.대체는 선택사항이지만, 나는 그것이 수행자인지 의심스럽다.몇 년 동안 사용한 후에 스트링에 대한 나의 가장 큰 문제는.형식은 통화의 길이가 다른 기능(Msg와 같은)으로 전달될 때 불편할 정도로 길지만, 그것은 가명 역할을 할 수 있는 맞춤 기능으로 돌아다니기 쉽다.
잘못된 테스트가 여러 번 반복됨 {} no %s을(를) 사용해야 함.
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "Hi " + i + "; Hi to you " + i * 2;
}
long end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format("Hi %s; Hi to you %s", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("Wrong use of the message format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format("Hi {0}; Hi to you {1}", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("Good use of the message format = " + ((end - start)) + " millisecond");
}
Concatenation = 88 millisecond
Wrong use of the message format = 1075 millisecond
Good use of the message format = 376 millisecond
문자열 연결과 문자열을 비교할 수 없음.위의 프로그램으로 포맷하십시오.
또한 스트링 사용 위치를 변경하여 사용해 보십시오.코드 블록에서 아래와 같이 포맷 및 연결
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
for( int i=0;i<1000000; i++){
String s = String.format( "Hi %s; Hi to you %s",i, + i*2);
}
long end = System.currentTimeMillis();
System.out.println("Format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for( int i=0;i<1000000; i++){
String s = "Hi " + i + "; Hi to you " + i*2;
}
end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond") ;
}
포맷이 여기서 더 빨리 작동하는 것을 보면 놀랄 것이다.생성된 내부 개체가 릴리스되지 않을 수 있고 메모리 할당과 그에 따른 성능에 문제가 있을 수 있기 때문이다.
'programing' 카테고리의 다른 글
Vuex 업데이트 상태 (0) | 2022.04.26 |
---|---|
Enum과 Define 문 간의 차이 (0) | 2022.04.26 |
setsockopt(SO_REUSEADR)를 사용하는 방법 (0) | 2022.04.26 |
Vuex에서 Interval을 지우는 방법 (0) | 2022.04.26 |
요소 ui el 선택 옵션 워드랩 (0) | 2022.04.26 |