JavaScript에는 stringbuilder 클래스가 내장되어 있습니까?


답변:


320

Internet Explorer 용 코드를 작성해야하는 경우 배열 조인을 사용하는 구현을 선택했는지 확인하십시오. IE 에서 +또는 +=연산자로 문자열을 연결하면 속도가 매우 느립니다. IE6의 경우 특히 그렇습니다. 최신 브라우저 +=에서는 일반적으로 배열 조인만큼 빠릅니다.

많은 문자열 연결을 수행해야 할 때 일반적으로 배열을 채우고 문자열 빌더 클래스를 사용하지 않습니다.

var html = [];
html.push(
  "<html>",
  "<body>",
  "bla bla bla",
  "</body>",
  "</html>"
);
return html.join("");

push메소드는 여러 인수를 허용합니다.


7
그리고 출력을 인라인으로 생성하거나 모든 멤버가 리터럴 인 경우 [foo(), "bar", "baz"].join("");작동합니다.
Anonymous

1
Dropbox 링크가 거의 3 년 동안 작동 할 것으로 예상 할 수는 없지만 비교에 대해 궁금한 점이 있습니다.
Cornelius

1
@DaveWard, 귀하의 링크는 :( 고장
이반 Kochurkin

나는 더 많은 읽을 수 있도록이 찾아 해당 문자열 + 문자열 + 문자열
앤드류 에를리히

12
나는 push여러 가지 주장을 받아 들일 수 있다는 것을 몰랐다 . 당신이 배우는 임의의 것들.
Carcigenicate

55

방금 http://jsperf.com/javascript-concat-vs-join/2 에서 성능을 다시 확인했습니다 . 테스트 사례는 알파벳을 1,000 번 연결하거나 연결합니다.

현재 브라우저 (FF, Opera, IE11, Chrome)에서 "concat"은 "join"보다 약 4-10 배 빠릅니다.

IE8에서는 둘 다 동일한 결과를 반환합니다.

IE7에서 "join"은 불행히도 약 100 배 더 빠릅니다.


3
고마워 이것은 답변 목록에 부딪쳐 야합니다. IE10에서도 훨씬 빠릅니다 (현대 브라우저는 아니지만 알고있는 잠재적 NMCI 개발자를 위해 언급했습니다).
James Wilson

@Andreas 문자열이 읽히지 않아 실제 연결을 수행하지 않는 Chrome의 테스트가 Chrome에서 코드 경로에 도달하고 있다고 생각합니다. 그럼에도 불구하고 실행 속도는 여전히 훨씬 빠릅니다. jsperf.com/yet-another-string-concat-test/1
Joseph Lennox

37

아니요, 문자열 작성에 대한 기본 지원은 없습니다. 대신 연결을 사용해야합니다.

물론 문자열의 다른 부분으로 구성된 배열을 만든 다음 join()해당 배열 을 호출 할 수 있지만 사용중인 JavaScript 인터프리터에서 조인이 구현되는 방식에 따라 다릅니다.

str1+str2방법 의 속도와 방법 의 속도를 비교하기 위해 실험을했습니다 array.push(str1, str2).join(). 코드는 간단했다 :

var iIterations =800000;
var d1 = (new Date()).valueOf();
str1 = "";
for (var i = 0; i<iIterations; i++)
    str1 = str1 + Math.random().toString();
var d2 = (new Date()).valueOf();
log("Time (strings): " + (d2-d1));

var d3 = (new Date()).valueOf();
arr1 = [];
for (var i = 0; i<iIterations; i++)
    arr1.push(Math.random().toString());
var str2 = arr1.join("");
var d4 = (new Date()).valueOf();
log("Time (arrays): " + (d4-d3));

Windows 7 x64에서 Internet Explorer 8 및 Firefox 3.5.5에서 테스트했습니다.

처음에는 적은 수의 반복 (약 수백, 수천 개의 항목)을 테스트했습니다. 결과는 예측할 수 없었습니다 (때때로 문자열 연결에는 0 밀리 초가 걸리고 때로는 16 밀리 초가 걸리며 배열 결합과 동일 함).

카운트를 50,000으로 늘리면 브라우저마다 결과가 달랐습니다 .Internet Explorer에서 문자열 연결이 더 빨라졌고 (94 밀리 초) 조인이 느 렸습니다 (125 밀리 초). 파이어 폭스에서는 배열 조인이보다 빠릅니다 (113 밀리 초) 문자열 결합 (117 밀리 초)

그런 다음 카운트를 500'000으로 늘 렸습니다. 이제 두 브라우저에서 문자열 연결보다 속도array.join()느 렸습니다 . 문자열 연결은 Internet Explorer에서 937ms, Firefox에서 1155ms, Internet Explorer에서 배열 조인 1265, Firefox에서 1207ms였습니다.

Internet Explorer에서 "스크립트를 실행하는 데 시간이 너무 오래 걸리지"않고 테스트 할 수있는 최대 반복 횟수는 850,000입니다. 그런 다음 Internet Explorer는 문자열 연결의 경우 1593, 배열 결합의 경우 2046이었고 Firefox는 문자열 연결의 경우 2101, 배열 결합의 경우 2249입니다.

결과 -반복 횟수가 적은 경우 array.join()Firefox에서 더 빠를 수 있으므로 사용을 시도 할 수 있습니다. 숫자가 증가하면 string1+string2방법이 더 빠릅니다.

최신 정보

Internet Explorer 6 (Windows XP)에서 테스트를 수행했습니다. 프로세스가 100,000 회 이상 반복하여 테스트를 시도하면 프로세스가 즉시 응답하지 않고 종료되지 않았습니다. 40,000 회의 반복 결과

Time (strings): 59175 ms
Time (arrays): 220 ms

이는 Internet Explorer 6을 지원해야하는 array.join()경우 문자열 연결보다 빠른 방법을 선택하십시오 .


join()ECMAScript의 일부이며 모든 JavaScript 인터프리터가이를 구현합니다. 왜 "의존"합니까?
Eli Gray

그는 그것이 어떻게 구현되었는지를 의미했다. 루프에서 문자열이 한 번에 생성되는 것이 아니라 지속적으로 추가되는 방식으로 구현된다면 join을 사용하는 것은 의미가 없다.
John

그렇습니다, 그것은 실제로 의미했습니다. 내 영어를 용서해라 ;-) 두 브라우저에서 어떤 방법이 작동하는지 비교 한 결과를 추가했습니다. 알다시피, 그것은 다릅니다.
naivists

2
IE6은 언제나 그렇듯이 예외입니다 :)
Gordon Tucker

10
IE6 사용자는 모든 것을 느리게하는 데 익숙합니다. 나는 그들이 당신을 탓할 것이라고 생각하지 않습니다.
Lodewijk

8

이 코드는 약간의 변경으로 원하는 경로처럼 보입니다.

append 메소드를 다음과 같이 변경하려고합니다. 숫자 0을 수락하도록 변경하고 this추가하여 연결할 수 있도록 반환했습니다 .

StringBuilder.prototype.append = function (value) {
    if (value || value === 0) {
        this.strings.push(value);
    }
    return this;
}

NaN이 아닌 숫자와 비어 있지 않은 문자열 만 허용하는 이유는 무엇입니까? 귀하의 방법은 허용하지 않습니다 null, false빈 문자열, undefined또는 NaN.
Eli Gray

@ Ellijah-유효한 문자열과 숫자 이외의 것을 받아들이지 않으면 서 StringBuilder 클래스를 깨끗하게 유지하는 것을 선호합니다. 개인적인 취향 일뿐입니다.
Gordon Tucker

5

JavaScript의 ECMAScript 6 버전 (일명 ECMAScript 2015)에는 문자열 리터럴이 도입되었습니다 .

var classType = "stringbuilder";
var q = `Does JavaScript have a built-in ${classType} class?`;

작은 따옴표 대신 역 따옴표는 문자열을 묶습니다.


17
이 질문에 어떻게 대답합니까?
피터 Mortensen

@ Peter Mortensen,이 답변은 문자열을 만드는 또 다른 방법을 제공합니다. 원래 포스터는 어떤 유형의 문자열 작성기 기능을 찾고 있는지 지정하지 않았습니다.
테오 필 루스

1
이것은 질문에 대답하지 않습니다. 조금도.
Massimiliano Kraus

2

C #에서는 다음과 같은 작업을 수행 할 수 있습니다.

 String.Format("hello {0}, your age is {1}.",  "John",  29) 

JavaScript에서는 다음과 같은 작업을 수행 할 수 있습니다

 var x = "hello {0}, your age is {1}";
 x = x.replace(/\{0\}/g, "John");
 x = x.replace(/\{1\}/g, 29);

2
문자열 조인 대신 정규 표현식을 실행하는 것이 더 성능이
tic

또한 이것은 끔찍한 구현입니다. {0}교체 된 문자열에 포함 된 경우 중단됩니다 {1}.
ikegami

@ikegami 문자열은 변수가 아니며 상수이기 때문에 priori가 포함 된 것을 알고 있습니다.
스포츠

@sports, 코드 전체를 복사하여 붙여 넣는 것은 더 나쁜 생각입니다.
ikegami

비 캡처 그룹을 대체하는 $ 1 및 $ 2의 하나의 라이너 : x..replace (/ ([\ s \ S] *?) \ {0 \} ([\ s \ S] *?) \ {1 \} / g, "$ 1Tom $ 225")
T.CK 03.11.19

1

관심있는 사람들을 위해 Array.join을 호출하는 대안이 있습니다.

var arrayOfStrings = ['foo', 'bar'];
var result = String.concat.apply(null, arrayOfStrings);
console.log(result);

예상대로 출력은 문자열 'foobar'입니다. Firefox에서이 방법은 Array.join보다 성능이 우수하지만 + 연결로 성능이 뛰어납니다. String.concat에서는 각 세그먼트를 별도의 인수로 지정해야하므로 호출자는 실행중인 JavaScript 엔진에 의해 부과되는 인수 수 제한에 의해 제한됩니다. 한 번 봐 가지고 Function.prototype.apply의 ()의 문서 자세한 내용입니다.


"String.concat"이 정의되지 않았기 때문에 Chrome에서 실패합니다. 대신 ''.concat.apply ( '', arrayOfStrings)를 사용할 수 있습니다. 그러나 이것은 여전히 ​​매우 느린 방법입니다.
Andreas

1

이 기능을 정의했습니다.

function format() {
        var args = arguments;
        if (args.length <= 1) { 
            return args;
        }
        var result = args[0];
        for (var i = 1; i < args.length; i++) {
            result = result.replace(new RegExp("\\{" + (i - 1) + "\\}", "g"), args[i]);
        }
        return result;
    }

그리고 C #처럼 호출 할 수 있습니다 :

 var text = format("hello {0}, your age is {1}.",  "John",  29);

결과:

안녕하세요, 나이는 29 세입니다.


1
난 그게 좋아 ... C #처럼 보인다
Ayo Adesina

2
이 답변은 질문과 관련이 없습니다.
Massimiliano Kraus

0

JavaScript에서 많은 문자열 연결을 수행하면 템플릿을 찾기 시작합니다. Handlebars.js는 HTML과 JavaScript를 더 읽기 쉽게 유지합니다. http://handlebarsjs.com


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.