-
Notifications
You must be signed in to change notification settings - Fork 321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Investigate More Effective IR Caching format #5567
Comments
I have overridden
|
I tried to skip reading function bodies - not done yet. Need to investigate Another attempt was to separate the |
Further investigation of those 3s spends during deserialization suggests they may be appropriate - we are deserializing 48MB of --- a/engine/runtime/src/main/java/org/enso/compiler/Cache.java
+++ b/engine/runtime/src/main/java/org/enso/compiler/Cache.java
@@ -230,7 +239,7 @@
if (sourceDigestValid && blobDigestValid) {
Object readObject;
- System.err.println("reading from " + dataPath);
+ System.err.println("CacheRead " + getClass().getSimpleName() + " from " + dataPath + " size: " + dataPath.size());
try (ObjectInputStream stream = new ObjectInputStream(new ByteArrayInputStream(blobBytes)) {
{
enableResolveObject(true); this is the histogram of occurrences of various types inside of the biggest 3MB! large
the histogram can be printed by following program: import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class CountClasses {
public static void main(String... args) throws Exception {
Map<Class<?>,int[]> counter = new HashMap<>();
try (ObjectInputStream is = new ObjectInputStream(new FileInputStream(args[0])) {
{
enableResolveObject(true);
}
@Override
protected Object resolveObject(Object obj) throws IOException {
counter.putIfAbsent(obj.getClass(), new int[1]);
counter.get(obj.getClass())[0]++;
return obj;
}
}) {
var obj = is.readObject();
System.out.println("read " + obj.getClass());
var entries = new ArrayList<>(counter.entrySet());
entries.sort((o1, o2) -> o1.getValue()[0] - o2.getValue()[0]);
for (var e : entries) {
System.out.printf("%d\t%s\n", e.getValue()[0], e.getKey().getName());
}
}
}
} The next question: what can we do about this? |
This is not yet done. The new attempt, including |
Jaroslav Tulach reports a new STANDUP for today (2023-03-20): Progress: - test generating ImportExports caches: de60b35 Next Day: Vacation - travel to Bulgaria.
|
I now have a plan to move forward. The plan is inspired by our work on the new parser. In #3723 we were running the old and new parser next to each other and we were comparing the results. Let's create a testing infrastructure to run the IR builder without caches and the IR builder with caches next to each other and compare their results. When they differ - we'd have an easy to debug test case to fix. The skeleton of such test is already available in IR_5567 branch. |
Jaroslav Tulach reports a new STANDUP for yesterday (2023-03-22): Progress: - catching up, building latest bits
Next Day: Back at full speed. |
Jaroslav Tulach reports a new STANDUP for yesterday (2023-03-23): Progress: - looking at Hubert's: #6045 (comment)
Next Day: Vacation: Parallel Giant Slalom at WCJ
|
Jaroslav Tulach reports a new STANDUP for yesterday (2023-03-27): Progress: - processing emails & reviews
Next Day: Integrate |
The primary delivery of this PR is a design of `SerdeCompilerTest` - a testing suite that allows us to write sample projects, parse them with and without caches and verify they still produce the same `IR`. This is a similar idea to #3723 which compared the old and new parser `IR`s. With infrastructure like this we can start addressing #5567 without any (significant) fear of breaking something essential.
The testing infrastructure has been integrated. Let's close this (too) long open issue and schedule smaller ones for subsequent work. Like: |
Summary
Measurements performed during the investigation of LS+engine startup (#5027) indicate that it takes more than
2.5s
to load “IR caches” (described here). The current format is using standard Java serialization/deserialization and is subject to slow initialization. It uses reflection behind the scene and reflection is slow to initialize. . We have to either limit the number of loadedIR
objects or change the format to a more efficient one.Value
Modify the current format slightly to avoid deserializing things that aren't needed. For example the "resolve import exports compiler pass" forces deserialization of all the
IR
files of a given library. Such deserialization includes also method bodies which is unnecessary. Either store the information for resolving imports separately or makeIR
multi-tier.Specification
@kustosz suggestion: let's say you have a 2-tier serialization solution, something like:
Deserialization of
SerializedModule
would be fast, it's a small structure (except theSerializedMethod
s, but these are just bytes arrays – very fast to read). Then you just have a lazy root node that keeps thatSerializedMethod
and reads it when it is first calledAcceptance Criteria & Test Cases
Pass existing tests. Perform measurement of startup according to the methodology and confirm the deserialization time drops down.
The text was updated successfully, but these errors were encountered: