-
Notifications
You must be signed in to change notification settings - Fork 659
Improve startup and opening times by speeding up changes to recent files #15759
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
base: master
Are you sure you want to change the base?
Changes from all commits
f9eb37d
2104a1f
28fc316
b82f6f1
21e5e2f
f9ba056
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -465,51 +465,81 @@ private void RefreshFileList(ObservableCollection<StartPageListItem> files, | |||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private Dictionary<string, object> DeserializeJsonFile(string filePath) | ||||||||||||||||
private readonly string[] jsonKeys = { "Description", "Thumbnail", "Author" }; | ||||||||||||||||
private readonly Dictionary<string, object> propertyLookup = []; | ||||||||||||||||
private static DefaultJsonNameTable propertyTable = null; | ||||||||||||||||
|
||||||||||||||||
private class GraphData | ||||||||||||||||
{ | ||||||||||||||||
if (DynamoUtilities.PathHelper.isValidJson(filePath, out string jsonString, out Exception ex)) | ||||||||||||||||
{ | ||||||||||||||||
return JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString); | ||||||||||||||||
} | ||||||||||||||||
else | ||||||||||||||||
public string Author = ""; | ||||||||||||||||
public string Description = ""; | ||||||||||||||||
public string Thumbnail = ""; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private GraphData DeserializeJsonFileTest(string filePath) | ||||||||||||||||
{ | ||||||||||||||||
return JsonConvert.DeserializeObject<GraphData>(File.ReadAllText(filePath)); | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so ? was this any faster/slower than streaming? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if these are the numbers : https://github.com/DynamoDS/Dynamo/pull/15759/files#r1932364787 |
||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private Dictionary<string, string> DeserializeJsonFile(string filePath) | ||||||||||||||||
{ | ||||||||||||||||
if (propertyTable == null) | ||||||||||||||||
{ | ||||||||||||||||
if(ex is JsonReaderException) | ||||||||||||||||
propertyTable = new DefaultJsonNameTable(); | ||||||||||||||||
foreach (var pn in jsonKeys) | ||||||||||||||||
{ | ||||||||||||||||
DynamoViewModel.Model.Logger.Log("File is not a valid json format."); | ||||||||||||||||
propertyLookup[pn] = propertyTable.Add(pn); | ||||||||||||||||
} | ||||||||||||||||
else | ||||||||||||||||
{ | ||||||||||||||||
DynamoViewModel.Model.Logger.Log("File is not valid: " + ex.StackTrace); | ||||||||||||||||
} | ||||||||||||||||
return null; | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private const string BASE64PREFIX = "data:image/png;base64,"; | ||||||||||||||||
|
||||||||||||||||
private string GetGraphThumbnail(Dictionary<string, object> jsonObject) | ||||||||||||||||
{ | ||||||||||||||||
jsonObject.TryGetValue("Thumbnail", out object thumbnail); | ||||||||||||||||
try | ||||||||||||||||
{ | ||||||||||||||||
var data = new Dictionary<string, string>(); | ||||||||||||||||
// JsonTextRead will automatically dispose of the stream reader | ||||||||||||||||
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) | ||||||||||||||||
using (var jr = new JsonTextReader(new StreamReader(fs)) { PropertyNameTable = propertyTable }) | ||||||||||||||||
{ | ||||||||||||||||
while(jr.Read()) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So is this low level parsing faster then just doing a Json.deserialize to a new class containing only the 3 properties that we need ? Doing the latter would at least be cleaner and less error prone There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The advantage of doing it this way, is that we don't have to read the entire content of the dyn file upfront. I'll do some more testing and see if deseralizing into a new mini class will work better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The properties There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed that it is messier. However you have to remember that this happens every time you open the home page and every time you open a new graph. Every ~100ms we can shave off from the overall process means a noticeably better user experience overall. I did some quick tests and got some rough numbers:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The order of the json properties is not enforced or guaranteed. I've not yet looked deeply at this PR - is the logic dependent on the tokens being in a specific order? We can enforce them using the order attribute but that won't help us with existing graphs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not dependent on the order. If those attributes were always first, it would make it faster I guess There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. example:
|
||||||||||||||||
{ | ||||||||||||||||
if (data.Count == jsonKeys.Length) | ||||||||||||||||
{ | ||||||||||||||||
break; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
if (string.IsNullOrEmpty(thumbnail as string)) return string.Empty; | ||||||||||||||||
if (jr.Depth != 1) | ||||||||||||||||
{ | ||||||||||||||||
continue; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
var base64 = String.Format("{0}{1}", BASE64PREFIX, thumbnail as string); | ||||||||||||||||
if (jr.TokenType == JsonToken.PropertyName) | ||||||||||||||||
{ | ||||||||||||||||
foreach (var prop in propertyLookup) | ||||||||||||||||
{ | ||||||||||||||||
if (jr.Value == prop.Value) | ||||||||||||||||
{ | ||||||||||||||||
data[prop.Key] = jr.ReadAsString() ?? ""; | ||||||||||||||||
break; | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
return base64; | ||||||||||||||||
return data; | ||||||||||||||||
} | ||||||||||||||||
catch | ||||||||||||||||
{ | ||||||||||||||||
DynamoViewModel.Model.Logger.Log("File is not a valid json format."); | ||||||||||||||||
return null; | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private string GetGraphDescription(Dictionary<string, object> jsonObject) | ||||||||||||||||
{ | ||||||||||||||||
jsonObject.TryGetValue("Description", out object description); | ||||||||||||||||
|
||||||||||||||||
return description as string; | ||||||||||||||||
} | ||||||||||||||||
private const string BASE64PREFIX = "data:image/png;base64,"; | ||||||||||||||||
|
||||||||||||||||
private string GetGraphAuthor(Dictionary<string, object> jsonObject) | ||||||||||||||||
private string GetGraphThumbnail(Dictionary<string, string> jsonObject) | ||||||||||||||||
{ | ||||||||||||||||
jsonObject.TryGetValue("Author", out object author); | ||||||||||||||||
|
||||||||||||||||
return author as string; | ||||||||||||||||
jsonObject.TryGetValue("Thumbnail", out var thumbnail); | ||||||||||||||||
return string.IsNullOrEmpty(thumbnail) ? string.Empty : $"{BASE64PREFIX}{thumbnail}"; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
private void HandleRegularCommand(StartPageListItem item) | ||||||||||||||||
|
@@ -559,9 +589,12 @@ private void HandleExternalUrl(StartPageListItem item) | |||||||||||||||
try | ||||||||||||||||
{ | ||||||||||||||||
var jsonObject = DeserializeJsonFile(filePath); | ||||||||||||||||
var description = jsonObject != null ? GetGraphDescription(jsonObject) : string.Empty; | ||||||||||||||||
//var test = DeserializeJsonFileTest(filePath); | ||||||||||||||||
var description = jsonObject?.TryGetValue("Description", out var description_) == true ? | ||||||||||||||||
description_ : string.Empty; | ||||||||||||||||
var author = jsonObject?.TryGetValue("Author", out var author_) == true ? | ||||||||||||||||
author_ : Resources.DynamoXmlFileFormat; | ||||||||||||||||
var thumbnail = jsonObject != null ? GetGraphThumbnail(jsonObject) : string.Empty; | ||||||||||||||||
var author = jsonObject != null ? GetGraphAuthor(jsonObject) : Resources.DynamoXmlFileFormat; | ||||||||||||||||
var date = DynamoUtilities.PathHelper.GetDateModified(filePath); | ||||||||||||||||
|
||||||||||||||||
return (description, thumbnail, author, date); | ||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change all about reordering the serialized data ?
I think @mjkkirschner mentioned an easier way to control the order : [JsonProperty(Order = 1)]
But seeing numbers here https://github.com/DynamoDS/Dynamo/pull/15759/files#r1932364787 is this still worth doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. Unfortunately, using
[JsonProperty(Order = N)]
is not applicable in our case because there's a custom json serializer implementation that writes the properties line by line. That's why I modified it this way