Last active
August 8, 2019 11:13
-
-
Save JarvisCraft/d392513836a6a04460f1e2d539103bd1 to your computer and use it in GitHub Desktop.
ultimate-messenger Placeholders benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Hello world | |
Hello, {user:name} | |
Hello, {user:name}, how are you? | |
Hello, {user:name}, how are you? | |
Hi, {user:name} your ping is {user:ping} | |
Hi, dear {user:name}, btw, {user:name}, how are you feeling? Also, what are you doing? | |
Your ping is {user:ping}. | |
Speaking about your friends, {user:friends}, how are they feeling? | |
Do your friends ({user:friends}) feel like they want to test your ping ({user:ping}? | |
This {user:magic could have been a great placeholder, but it isn't, lol | |
Hello static world full of errors and exceptions through which you can pass through | |
Instead of simply copy-pasting this, dear {user:name}, you could have just testes you UUID {user:uuid} | |
Btw, is it fine to live with age {user:age} already having so many friends: {user:friends} | |
Why did you take nickname {user:nick}, isn't DOMYENYATOR25565 better? lol | |
Btw, it's nice to see you coding, {user:name}, because otherwise {user:friends} all would be sad | |
This is another string which you'll have to parse, sry | |
It's not the end yet, mr.{user:name}, I know where you live! (here, lol) | |
- How old are you? | |
- I am {user:age} years old, and you? | |
- Me to | |
- Lol | |
- Lol | |
- Know that feel bro | |
- Why didn't ypu say feeling? At your age of {user:age} you should know it | |
- Let's say it's all due to my latency? | |
- ? | |
- I mean ping, {user:ping} it is | |
- Oh, fine | |
- Know that feel bro | |
- Seriously? | |
- yep ))0)0)00)00)) | |
I wish I could omit writing those strings | |
Seriously | |
Somebody | |
{user:uuid}: {user:name}'s age is {user:age}, his ping is {user:ping} and he has a lot of friends ({user:friends}) | |
Also, {user:name}'s nick is {user:nick}. Did you hear me? {user:nick}, {user:nick} I said. {user:nick}{user:nick} | |
{user:nick}{user:nick}{user:nick}{user:nick}{user:nick}{user:age}{user:nick}{user:id}{user:friends}{haha} | |
<3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Benchmark Mode Cnt Score Error Units | |
TextModelVsFormatVsReplaceBenchmark.test_Placeholders_format avgt 100 968689,804 ± 171022,990 ns/op | |
TextModelVsFormatVsReplaceBenchmark.test_String_replace avgt 100 2103251,907 ± 670708,009 ns/op | |
TextModelVsFormatVsReplaceBenchmark.test_TextModel_getText avgt 100 366084,479 ± 119197,109 ns/op |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.progrm_jarvis.ultimatemessenger; | |
import org.openjdk.jmh.annotations.*; | |
import org.openjdk.jmh.infra.Blackhole; | |
import org.openjdk.jmh.runner.Runner; | |
import org.openjdk.jmh.runner.RunnerException; | |
import org.openjdk.jmh.runner.options.OptionsBuilder; | |
import ru.progrm_jarvis.ultimatemessenger.format.model.AsmTextModelFactory; | |
import ru.progrm_jarvis.ultimatemessenger.format.model.TextModel; | |
import ru.progrm_jarvis.ultimatemessenger.format.model.TextModelFactory; | |
import ru.progrm_jarvis.ultimatemessenger.format.placeholder.Placeholders; | |
import ru.progrm_jarvis.ultimatemessenger.format.placeholder.SimplePlaceholders; | |
import ru.progrm_jarvis.ultimatemessenger.testobject.User; | |
import java.io.BufferedReader; | |
import java.io.File; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.util.*; | |
import java.util.concurrent.ThreadLocalRandom; | |
import java.util.concurrent.TimeUnit; | |
import java.util.stream.Collectors; | |
@Warmup(iterations = 20) | |
@Measurement(iterations = 20) | |
@State(Scope.Benchmark) | |
@BenchmarkMode(Mode.AverageTime) | |
@OutputTimeUnit(TimeUnit.NANOSECONDS) | |
public class TextModelVsFormatVsReplaceBenchmark { | |
private User[] users; | |
private Placeholders<User> placeholders; | |
private TextModelFactory<User> textModelFactory; | |
private String[] strings1; | |
private String[] strings2; | |
private TextModel<User>[] textModels; | |
public static void main(final String... args) throws RunnerException { | |
new Runner( | |
new OptionsBuilder() | |
.include(TextModelVsFormatVsReplaceBenchmark.class.getCanonicalName()) | |
.forks(5) | |
.build() | |
).run(); | |
} | |
private static String toString(final Set<String> set) { | |
if (set.isEmpty()) return "/"; | |
if (set.size() == 1) return set.iterator().next(); | |
return String.join(", ", set); | |
} | |
@Setup | |
public void setUp() throws IOException { | |
placeholders = SimplePlaceholders.<User>builder() | |
.build(); | |
placeholders.add("user", (value, user) -> { | |
switch (value) { | |
case "name": return user.getName(); | |
case "uuid": return user.getUuid().toString(); | |
case "age": return Integer.toString(user.getAge()); | |
case "friends": return toString(user.getFriendNames()); | |
case "nick": return user.getNickname(); | |
case "ping": return Integer.toString(user.getPing()); | |
default: return "???"; | |
} | |
}); | |
textModelFactory = new AsmTextModelFactory<>(); | |
users = new User[ThreadLocalRandom.current().nextInt(128)]; | |
for (int i = 0; i < users.length; i++) users[i] = User.createRandom(); | |
{ // values testes | |
final List<String> strings = new ArrayList<>(); | |
final List<TextModel<User>> textModels = new ArrayList<>(); | |
System.out.println(new File("")); | |
try (final BufferedReader reader = new BufferedReader( | |
new InputStreamReader(getClass().getResourceAsStream("/LinesWithPlaceholders.txt")) | |
)) { | |
reader | |
.lines() | |
.collect(Collectors.toList()) | |
.forEach(text -> { | |
strings.add(text); | |
textModels.add(placeholders.parse(textModelFactory, text)); | |
}); | |
} | |
this.strings1 = strings.toArray(new String[0]); | |
this.strings2 = strings.toArray(new String[0]); | |
//noinspection unchecked | |
this.textModels = textModels.toArray(new TextModel[0]); | |
} | |
} | |
@Benchmark | |
public void test_String_replace(final Blackhole blackhole) { | |
for (final User user : users) for (final String string : strings1) blackhole.consume( | |
string | |
.replace("{user:name}", user.getName()) | |
.replace("{user:uuid}", user.getUuid().toString()) | |
.replace("{user:age}", Integer.toString(user.getAge())) | |
.replace("{user:friends}", toString(user.getFriendNames())) | |
.replace("{user:nick}", user.getNickname()) | |
.replace("{user:ping}", Integer.toString(user.getPing())) | |
); | |
} | |
@Benchmark | |
public void test_Placeholders_format(final Blackhole blackhole) { | |
for (final User user : users) for (final String string : strings2) blackhole | |
.consume(placeholders.format(string, user)); | |
} | |
@Benchmark | |
public void test_TextModel_getText(final Blackhole blackhole) { | |
for (final User user : users) for (final TextModel<User> textModel : textModels) blackhole | |
.consume(textModel.getText(user)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ru.progrm_jarvis.ultimatemessenger.testobject; | |
import java.util.HashSet; | |
import java.util.Iterator; | |
import java.util.Set; | |
import java.util.UUID; | |
import java.util.concurrent.ThreadLocalRandom; | |
public class User { | |
// final | |
private final String name; | |
private final int age; | |
private final UUID uuid; | |
// non-final | |
private int ping; | |
private String nickname; | |
private Set<String> friendNames = new HashSet<>(); | |
public User(final String name, final int age, final UUID uuid) { | |
this.name = name; | |
this.age = age; | |
this.uuid = uuid; | |
} | |
public static User createRandom() { | |
final ThreadLocalRandom random = ThreadLocalRandom.current(); | |
final User user = new User( | |
Integer.toString(random.nextInt(), Character.MAX_RADIX), random.nextInt(), UUID.randomUUID() | |
); | |
{ | |
final int friendCount = random.nextInt(64); | |
for (int i = 0; i < friendCount; i++) { | |
if (random.nextInt() % 4 == 0) user.removeRandomFriend(); | |
user.addFriend(Integer.toString(random.nextInt(), Character.MAX_RADIX)); | |
} | |
} | |
user.setNickname(Integer.toString(random.nextInt(), Character.MAX_RADIX)); | |
user.setPing(random.nextInt()); | |
return user; | |
} | |
public String getName() { | |
return name; | |
} | |
public int getAge() { | |
return age; | |
} | |
public UUID getUuid() { | |
return uuid; | |
} | |
public int getPing() { | |
return ping; | |
} | |
public String getNickname() { | |
return nickname; | |
} | |
public Set<String> getFriendNames() { | |
return friendNames; | |
} | |
public void setPing(final int ping) { | |
this.ping = ping; | |
} | |
public void setNickname(final String nickname) { | |
this.nickname = nickname; | |
} | |
public void addFriend(final String friendName) { | |
this.friendNames.add(friendName); | |
} | |
public void removeRandomFriend() { | |
final Iterator<String> iterator = this.friendNames.iterator(); | |
if (iterator.hasNext()) { | |
iterator.next(); | |
iterator.remove(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment