인텔리제이에서 여러 문자열을 더할때 stringbuilder로 주루륵 이어나가면 경고 메세지가 나옴.
인텔리제이는 별다른 조건없이 문자열 여러개를 단순 더할때는 + 연산자로 더하라고 권장함
하지만 우리는 배웠지!
자바에서 유일하게 연산자 오버로딩이 적용되어 있는 string의 덧셈은 두개의 문자열을 합친 크기만큼의 string을 만들어 두 문자열의 모든 문자를 복사함. 여러 문자열을 더할수록 상당히 비효율 적이기에 stringbuilder 사용을 고려하라고 배움
그렇다면 인텔리제이는 멍청이인가? 그건 아님 힌트는 컴파일된 class파일을 까보면 알 수 있음.
우리가 무지성으로 +을 통해 연결한 문자열들을 컴파일러가 stringbuilder를 사용해 최적화 시켜놓은걸 확인할 수 있음.
그렇다고 하더라도 ide가 구지 스트링 빌더보다 +사용을 권장하는 이유는 잘 모르겠음 추측하기로는 컴파일러가 최적화 할때에 여러 조건에따라 직접 빌더를 사용하는것보다 더 효율적인 방법을 찾아줄 수 있을것이라고 생각됨.
님들 생각이나 이유 아는 사람은 댓글좀
인텔리제이는 별다른 조건없이 문자열 여러개를 단순 더할때는 + 연산자로 더하라고 권장함
하지만 우리는 배웠지!
자바에서 유일하게 연산자 오버로딩이 적용되어 있는 string의 덧셈은 두개의 문자열을 합친 크기만큼의 string을 만들어 두 문자열의 모든 문자를 복사함. 여러 문자열을 더할수록 상당히 비효율 적이기에 stringbuilder 사용을 고려하라고 배움
그렇다면 인텔리제이는 멍청이인가? 그건 아님 힌트는 컴파일된 class파일을 까보면 알 수 있음.
우리가 무지성으로 +을 통해 연결한 문자열들을 컴파일러가 stringbuilder를 사용해 최적화 시켜놓은걸 확인할 수 있음.
그렇다고 하더라도 ide가 구지 스트링 빌더보다 +사용을 권장하는 이유는 잘 모르겠음 추측하기로는 컴파일러가 최적화 할때에 여러 조건에따라 직접 빌더를 사용하는것보다 더 효율적인 방법을 찾아줄 수 있을것이라고 생각됨.
님들 생각이나 이유 아는 사람은 댓글좀
비동기 문제 일껄 아마
아마 그래서 String에서 최적화 안해줄듯 싶은데
동시성 문제때문이면 컴파일러가 stringbuilder로 최적화 하는 이유가 설명이 안됨. 그럼 컴파일러가 동시성 문제 발생가능성을 스스로 체크하고 스트링 버퍼나 혹은 덧셈기호로 최적화 해낼 수 있다는 뜻임?
생각보다 언어가 ㅈㄴ 쓰레기라서 그럼
원래 파이프라이닝 최적화되어있으면 변수 순서나 이런건 알아서 최적화해주고, unsigned연산만 있으면 unsigend 처리하고 비동기 프로그래밍 없다 싶으면 builder 쓰고 입출력 버퍼 순서대로 하는 거 필요 없다 싶으면 모았다가 처리하고 이런거 자동화해줘야 되는데
안해줌
그거 class 까서 +라고 했는데 아마 거기 메소드 중에 비동기 동기 관련 메소드가 있을껄
ㄴㄴ 클래스 까서 builder 사용했음 그럼 비동기 코드가 있다면 빌더로 최적화 안하고 + 남긴다는거지? 그럼 지원 하는거네 다른 언어들도 결국 컴파일러가 해당 내용들 최적화 해주는거니 자바도 컴파일러가 지원한다고 봐야하는거 아님?
https://madplay.github.io/post/difference-between-string-stringbuilder-and-stringbuffer-in-java
그게 먼소리야 최적화 했으면 연산이 안 들어가야지 근데 생각해보니 어셈 생각해보면 오히려 그게 비효율적일 수도 있을 것 같기도하고..
실제로 라이브러리 뜯어보면 해당 코드도 다 공간을 잡아먹긴하는데 시간에 영향을 주는지 모르겠네
아마 님 말대로 시간에 영향을 줄 것 같기도 하다 그러니까 추상화 단점이라고도 볼 수 있을듯
인텔리제이가 옳다
어차피 뭘하든 바이트코드 까보면 StringBuilder 쓰게되어있음
글고 코드에 제일 비효율적인건 += 연산같은거로 계속 더해줄경우인거로아는데
String 은 내가 기억하기로 불변 char[] 인 반면 StringBuilder 는 공간 부족하면 새 어레이 만들어서 쭉 복사하느라 그나마 str = str + "" 형태에 비해서는 효율적인거고 여러개를 그냥 + 로 붙이는거는 상관없을텐데
String은 +=나 +를 이으나 같지 않음? 바이트 코드상에서는 정적 문자열 +로만 이으면 한개의 문자열로 자동 최적화 하는건 아는데 결국 어떤 문자열이 들어올지 모르는 경우엔 두개가 같자너
+= 연산은 그 객체를 버리는거까지해야하고 새 String = + + + 연산에서는 상관없다아님?
새 스트링 a + b + c 연산도 a b c 각각의 스트링 객체와 a+b시에 결과가 임시로 저장될 객체, 그 결과와 +c가 저장될 새 객체가 필요함 다만 a, b가 정적 문자열이라면 ab는 최적화 되서 컴파일 타임에 하나의 문자열 객체로 바뀜
StringBuilder 를 쓰도록되어있는데 a+b를 저장할 객체가 필요했나?
;; 빌더 최적화 안된다는 가정 아님? +=랑 +연산 비교하길래 차후 빌더최적화 없을때 이야기하는줄 빌더로 최적화 고려하면 당연히 +연산 잇는게 최선이지
빌더 최적화는 항상일어나는거아니였나? 내가 몰랐던게 또 있는건가
위에 얘기하던게 그거임 항상 빌더로 최적화 된다면 ide가 구지 경고를 내는 이유를 모르겠다는거고 그렇다면 빌더 말고 다른 최적화가 존재한다는 뜻 아닐까 싶어서 혹시 비동기로 문자열을 다루는 코드가 존재한다면 버퍼로 최적화하거나 +연산을 그냥 두는건가? 얘기 하던건데 일단 여기 댓글은 그냥 내가 이해 잘못한거 빌더 최적화가 없다고 가정하고 차이 말하는줄
내가 객체를 만들어서 쓰면 로컬 변수가 하나 더 생기는거랑 어차피 컴파일되면 똑같은일 하니까 코드 굳이 그렇게 쓰지말고 + 로 묶어버리라는거아닐까
Replace StringBuilder to String 하라는거 무시하고 컴파일돌려봤는데 일단 뭐 라벨 개수도 줄고 해서그런건가
결론적으로는 실험해보니까 5억번정도 돌렸을때 미리 객체 만들고나서 append하고 setLength(0) 로 하니까 2초정도 빠르긴한데 이쯤되면 그냥 가독성탓에 저렇게 하라는거인듯