Java-da String və StringBuilder Performans Müqayisəsi: JMH Benchmark Testi
Java proqramlaşdırmasında string manipulyasiyası geniş istifadə edilir, lakin hansı metodun performans baxımından daha üstün olduğunu bilmək vacibdir. Bu məqalədə String və StringBuilder arasında performans fərqini ölçmək üçün JMH (Java Microbenchmark Harness) istifadə edəcəyik. JMH, Java proqramlarının mikrosəviyyədə performans ölçülməsi üçün nəzərdə tutulmuş kitabxanadır.
Niyə String və StringBuilder Müqayisə Edilməlidir?
Java-da String
dəyişməz (immutable) bir obyekt olaraq dizayn edilmişdir. Buna görə hər dəfə bir String
birləşdirmə etdikdə yeni bir obyekt yaradılır. Əksinə, StringBuilder
dəyişkən (mutable) bir obyekt olaraq, string manipulyasiyalarını daha səmərəli şəkildə həyata keçirir. Bunun necə işlədiyini performans testləri ilə araşdıracağıq.
Bu testdə Java-da String
və StringBuilder
istifadə edərək mətn birləşdirmənin (concatenation
) performans fərqini yoxladım.
package com.javaazerbaycan;
import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
public class StringVsStringBuilderBenchmark {
private static final String BASE_STRING = "Java";
private static final int ITERATIONS = 1000;
@Benchmark
public String testStringConcatenation() {
String result = BASE_STRING;
for (int i = 0; i < ITERATIONS; i++) {
result += " Azerbaijan";
}
return result;
}
@Benchmark
public String testStringBuilderAppend() {
StringBuilder builder = new StringBuilder(BASE_STRING);
for (int i = 0; i < ITERATIONS; i++) {
builder.append(" Azerbaijan");
}
return builder.toString();
}
}
Testin Məqsədi
String
və StringBuilder
ilə çoxsaylı əməliyyatlar zamanı hansının daha effektiv olduğunu müəyyən etməkdir. Bunun üçün aşağıdakılar yoxlanılır:
-
testStringConcatenation
Metodu:- Bu metodda
String
obyektindən istifadə edərək mətn birləşdirmə aparılır. - Hər bir birləşdirmə zamanı yeni bir
String
obyekti yaradılır, çünkiString
immutable-dır (dəyişməzdir). Bu, performans baxımından daha çox yaddaş və CPU sərfi deməkdir.
- Bu metodda
-
testStringBuilderAppend
Metodu:- Bu metodda
StringBuilder
obyektindən istifadə olunur.StringBuilder
mutable-dır (dəyişdirilə bilən). - Mətn birləşdirmə əməliyyatları mövcud obyekt daxilində aparılır, bu da daha az yaddaş sərfi və daha sürətli icra ilə nəticələnir.
- Bu metodda
Testdəki Parametrlər
@BenchmarkMode(Mode.Throughput)
: Saniyə ərzində neçə əməliyyat icra olunduğunu ölçür.@OutputTimeUnit(TimeUnit.MILLISECONDS)
: Ölçü vahidinin millisaniyə olduğunu göstərir.@State(Scope.Thread)
: Hər thread üçün ayrıcaState
təmin edir, bu, testlərin izolyasiya olunmuş şəraitdə icrasını təmin edir.
Necə İşləyir?
- Hər bir metod 1000 iterasiya ilə eyni("Java") string-ə " Azerbaijan" əlavə edir.
JMH
(Java Microbenchmark Harness
) vasitəsilə hər iki metod icra olunur və onların performansı müqayisə edilir:testStringConcatenation
çoxlu obyekt yaradıldığı üçün daha yavaşdır.testStringBuilderAppend
daha az resurs istifadə etdiyi üçün daha sürətlidir.
Testdən Nəticə
Benchmark Mode Cnt Score Error Units
StringVsStringBuilderBenchmark.testStringBuilderAppend thrpt 25 120.505 ± 2.578 ops/ms
StringVsStringBuilderBenchmark.testStringConcatenation thrpt 25 2.017 ± 0.064 ops/ms
JMH testinin nəticələrində aşağıdakı sütunlar var və hər biri müəyyən mənanı ifadə edir:
Mode
: İşləmə rejimi
Test zamanı hansı performans ölçmə rejimindən istifadə edildiyini göstərir.
Bu testdə Throughput(thrpt)
rejimindən istifadə etdik, yəni saniyədə neçə əməliyyatın başa çatdırıldığını ölçdük.
Cnt
: Təkrar sayı
Testin neçə dəfə təkrarlandığını göstərir.
Bu, testin dəqiq və sabit nəticə verməsi üçün istifadə edilir. Adətən, yüksək təkrar sayı testin daha sabit nəticələr verməsinə kömək edir.
Score
: Performans göstəricisi
Bu sütun testin nəticələrini ədədi dəyərlə ifadə edir.
Throughput
rejimində: Saniyədə yerinə yetirilən əməliyyatların orta sayı.
Məsələn: 120.505 ops/ms deməkdir ki, test zamanı hər millisaniyədə orta hesabla 120 əməliyyat başa çatıb.
Error
: Xətanın dərəcəsi
Test nəticələrinin dəqiq olmadığını nəzərə alaraq, orta nəticənin nə qədər dəyişə biləcəyini göstərir.
Məsələn:
Score = 120.505 ± 2.578 ops/ms
deməkdir ki, faktiki nəticə 120.505 ilə (120.505 ± 2.578) arasında ola bilər.
Yəni, nəticənin etibarlılığına dair bir intervalla təmin edilir.
Units
: Ölçü vahidi
Test nəticələrinin hansı vahidlərdə göstərildiyini bildirir.
Bu testdə:
ops/ms
: Millisaniyə başına əməliyyatların sayı.
Digər rejimlərdə isə bu vahidlər ns/op
(hər əməliyyata nanosanilər) və ya başqa vahidlər ola bilər.
Ümumi İzah
Bu sütunlar JMH testlərinin nəticələrini dəqiq şəkildə ifadə edir:
Mode
: Testin necə ölçüldüyünü göstərir.Cnt
: Təkrarlanan testlərin sayını bildirir.Score
: Performans göstəricisidir (yüksək rəqəm daha yaxşıdır).Error
: Nəticənin qeyri-dəqiqliyini ifadə edir.Units
: Ölçü vahidini göstərir.
Nəticə etibarilə bu test göstərdi ki, StringBuilder
string manipulyasiyaları üçün performans baxımından daha effektivdir, xüsusilə dövrlərdə böyük miqdarda əməliyyat aparılarkən. Sadə əməliyyatlar üçün String
istifadə etmək rahat olsa da, mürəkkəb və çox iterasiyalı ssenarilər üçün StringBuilder
seçilməsi tövsiyə olunur.
Əgər performans optimizasiyası ilə maraqlanırsınızsa, JMH kimi güclü alətlərin istifadəsi sizin işinizə böyük töhfə verəcəkdir.