Skip to content

Commit

Permalink
Performance Improvements:
Browse files Browse the repository at this point in the history
- Added `logExecutionTime` command line argument for detailed execution time logging.
- Optimized hash calculation for better performance.
- Memoized the results of a sequence used twice to avoid redundant calculations.
- Removed unnecessary use of the `StrJoin` function.
  • Loading branch information
usr3-1415 committed Sep 29, 2024
1 parent 022e126 commit 55633c4
Show file tree
Hide file tree
Showing 13 changed files with 229 additions and 110 deletions.
1 change: 1 addition & 0 deletions BackendAst/BackendAst.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<Compile Include="CalculateIcdHash.fs" />
<Compile Include="AssemblyInfo.fs" />
<Compile Include="DAstUtilFunctions.fs" />
<Compile Include="DastFold.fs" />
Expand Down
86 changes: 86 additions & 0 deletions BackendAst/CalculateIcdHash.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
module CalculateIcdHash

open System
open System.IO
open System.Numerics
open System.Security.Cryptography
open DAst

// Helper functions for serialization
let writeOption (writer: BinaryWriter) (writeValue: 'a -> unit) (opt: 'a option) =
match opt with
| Some value ->
writer.Write(true)
writeValue value
| None ->
writer.Write(false)

let writeList (writer: BinaryWriter) (writeItem: 'a -> unit) (lst: 'a list) =
writer.Write(lst.Length)
lst |> List.iter writeItem

let writeString (writer: BinaryWriter) (str: string) =
writer.Write(str)

let writeInt (writer: BinaryWriter) (i : int) =
writer.Write(i)

let writeBigInteger (writer: BinaryWriter) (bi: BigInteger) =
let bytes = bi.ToByteArray()
writer.Write(bytes.Length)
writer.Write(bytes)

let writeIcdTypeCol (writer: BinaryWriter) (icdTypeCol: IcdTypeCol) =
match icdTypeCol with
| TypeHash s ->
writer.Write(0uy) // Tag for TypeHash
writeString writer s
| IcdPlainType s ->
writer.Write(1uy) // Tag for IcdPlainType
writeString writer s

let writeIcdRowType (writer: BinaryWriter) (icdRowType: IcdRowType) =
let tag =
match icdRowType with
| FieldRow -> 0uy
| ReferenceToCompositeTypeRow -> 1uy
| LengthDeterminantRow -> 2uy
| PresentDeterminantRow -> 3uy
| ThreeDOTs -> 4uy
writer.Write(tag)

let writeIcdRow (w: BinaryWriter) (icdRow: IcdRow) =
writeOption w (writeInt w) icdRow.idxOffset
writeString w icdRow.fieldName
writeList w (writeString w) icdRow.comments
writeString w icdRow.sPresent
writeIcdTypeCol w icdRow.sType
writeOption w (writeString w) icdRow.sConstraint
writeBigInteger w icdRow.minLengthInBits
writeBigInteger w icdRow.maxLengthInBits
writeOption w (writeString w) icdRow.sUnits
writeIcdRowType w icdRow.rowType

let calcIcdTypeAssHash (t1: IcdTypeAss) =
use ms = new MemoryStream()
use w = new BinaryWriter(ms)

// Serialize the IcdTypeAss fields
writeOption w (writeString w) t1.asn1Link
writeOption w (writeString w) t1.acnLink
writeString w t1.name
writeString w t1.kind
writeList w (writeString w) t1.comments
writeBigInteger w t1.minLengthInBytes
writeBigInteger w t1.maxLengthInBytes
writeList w (writeIcdRow w) t1.rows

w.Flush()
ms.Position <- 0L
let bytes = ms.ToArray()
// Compute the hash
let hashAlgorithm = MD5.Create()
let hash = hashAlgorithm.ComputeHash(bytes)
Convert.ToHexString(hash)


27 changes: 16 additions & 11 deletions BackendAst/DAstACN.fs
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,11 @@ let handleAlignmentForAcnTypes (r:Asn1AcnAst.AstRoot)
let md5 = System.Security.Cryptography.MD5.Create()

let createIcdTas (r:Asn1AcnAst.AstRoot) (id:ReferenceToType) (icdAux:IcdArgAux) (td:FE_TypeDefinition) (typeDefinition:TypeDefinitionOrReference) nMinBytesInACN nMaxBytesInACN hasAcnDefinition =
(*
Slow Implementation. It has been replaced by CalculateIcdHash.fs.
We keep it here for reference.
let calcIcdTypeAssHash (t1:IcdTypeAss) =
let rec calcIcdTypeAssHash_aux (t1:IcdTypeAss) =
let calcIcdTypeAssHash_aux (t1:IcdTypeAss) =
let rws =
t1.rows |>
Seq.map(fun r -> sprintf "%A%A%A%A%A%A%A%A%A%A" r.idxOffset r.fieldName r.comments r.sPresent r.sType r.sConstraint r.minLengthInBits r.maxLengthInBits r.sUnits r.rowType) |>
Expand All @@ -193,11 +196,11 @@ let createIcdTas (r:Asn1AcnAst.AstRoot) (id:ReferenceToType) (icdAux:IcdArgAux)
let bytes = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes aa)
Convert.ToHexString bytes
calcIcdTypeAssHash_aux t1

*)
let icdRows, compositeChildren = icdAux.rowsFunc "" "" [];
let icdTas =
{
IcdTypeAss.linkId = id
IcdTypeAss.typeId = id
tasInfo = id.tasInfo
asn1Link = None;
acnLink = None;
Expand Down Expand Up @@ -227,7 +230,7 @@ let createIcdTas (r:Asn1AcnAst.AstRoot) (id:ReferenceToType) (icdAux:IcdArgAux)
hasAcnDefinition = hasAcnDefinition
hash = "" // will be calculated later
}
let icdHash = calcIcdTypeAssHash icdTas
let icdHash = CalculateIcdHash.calcIcdTypeAssHash icdTas
{icdTas with hash = icdHash}


Expand Down Expand Up @@ -337,13 +340,15 @@ let private createAcnFunction (r: Asn1AcnAst.AstRoot)
let icdAux, ns3 =
match icdResult with
| Some icdAux ->
let hasAcnDefinition = t.typeAssignmentInfo.IsSome && t.acnLocation.IsSome
let icdTas = createIcdTas r t.id icdAux td typeDefinition nMinBytesInACN nMaxBytesInACN hasAcnDefinition
let ns3 =
match ns2.icdHashes.TryFind icdTas.hash with
| None -> {ns2 with icdHashes = ns2.icdHashes.Add(icdTas.hash, [icdTas])}
| Some exList -> {ns2 with icdHashes = ns2.icdHashes.Add(icdTas.hash, icdTas::exList)}
Some icdTas, ns3
let foo () =
let hasAcnDefinition = t.typeAssignmentInfo.IsSome && t.acnLocation.IsSome
let icdTas = createIcdTas r t.id icdAux td typeDefinition nMinBytesInACN nMaxBytesInACN hasAcnDefinition
let ns3 =
match ns2.icdHashes.TryFind icdTas.hash with
| None -> {ns2 with icdHashes = ns2.icdHashes.Add(icdTas.hash, [icdTas])}
| Some exList -> {ns2 with icdHashes = ns2.icdHashes.Add(icdTas.hash, icdTas::exList)}
Some icdTas, ns3
TL "createIcdTas" foo
| None -> None, ns2
let ret =
{
Expand Down
5 changes: 3 additions & 2 deletions BackendAst/DAstUtilFunctions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,6 @@ and IcdTypeAss = {
canBeEmbedded : bool
hasAcnDefinition : bool
*)
let md5 = System.Security.Cryptography.MD5.Create()
let calcIcdTypeAssHash (t1:IcdTypeAss) =
Expand All @@ -1105,6 +1104,7 @@ let calcIcdTypeAssHash (t1:IcdTypeAss) =
let bytes = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes aa)
Convert.ToHexString bytes
calcIcdTypeAssHash_aux t1
*)

let serializeIcdTasToText (icdTypeAss: IcdTypeAss) =
let printRow (r:IcdRow) =
Expand All @@ -1124,6 +1124,7 @@ let serializeIcdTasToText (icdTypeAss: IcdTypeAss) =
//let aa = sprintf"%A%A%A%A%A%A%A%A%A" t1.acnLink t1.asn1Link t1.name t1.kind t1.comments t1.minLengthInBytes t1.maxLengthInBytes (rws) ("")
let rws = icdTypeAss.rows |> Seq.map printRow |> Seq.StrJoin "\n"
sprintf """
typeId = %s
acnLink = %A
asn1Link = %A
name = %A
Expand All @@ -1133,4 +1134,4 @@ let serializeIcdTasToText (icdTypeAss: IcdTypeAss) =
maxLengthInBytes = %A
rows =
%A
""" icdTypeAss.acnLink icdTypeAss.asn1Link icdTypeAss.name icdTypeAss.kind icdTypeAss.comments icdTypeAss.minLengthInBytes icdTypeAss.maxLengthInBytes rws
""" icdTypeAss.typeId.AsString icdTypeAss.acnLink icdTypeAss.asn1Link icdTypeAss.name icdTypeAss.kind icdTypeAss.comments icdTypeAss.minLengthInBytes icdTypeAss.maxLengthInBytes rws
63 changes: 38 additions & 25 deletions BackendAst/GenerateAcnIcd.fs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ let PrintAcnAsHTML stgFileName (r:AstRoot) =
//let f = r.Files |> Seq.find(fun x -> Path.GetFileNameWithoutExtension(x.FileName) = Path.GetFileNameWithoutExtension(fName))
//let tasNames = f.Modules |> Seq.collect(fun x -> x.TypeAssignments) |> Seq.map(fun x -> x.Name.Value) |> Seq.toArray
let content = tokens |> Seq.map(fun token -> colorize(token,tasNames))
icd_acn.EmitFilePart2 stgFileName (Path.GetFileName fName) (content |> Seq.StrJoin "")
icd_acn.EmitFilePart2 stgFileName (Path.GetFileName fName) (content )
)

let PrintAcnAsHTML2 stgFileName (r:AstRoot) (icdHashesToPrint:string list) =
Expand Down Expand Up @@ -100,8 +100,8 @@ let PrintAcnAsHTML2 stgFileName (r:AstRoot) (icdHashesToPrint:string list) =
//let f = r.Files |> Seq.find(fun x -> Path.GetFileNameWithoutExtension(x.FileName) = Path.GetFileNameWithoutExtension(fName))
//let tasNames = f.Modules |> Seq.collect(fun x -> x.TypeAssignments) |> Seq.map(fun x -> x.Name.Value) |> Seq.toArray
let content = tokens |> Seq.map(fun token -> colorize(token))
icd_acn.EmitFilePart2 stgFileName (Path.GetFileName fName) (content |> Seq.StrJoin "")
)
icd_acn.EmitFilePart2 stgFileName (Path.GetFileName fName) (content)
) |> Seq.toList

let foldGenericCon = GenerateUperIcd.foldGenericCon
let foldRangeCon = GenerateUperIcd.foldRangeCon
Expand Down Expand Up @@ -603,7 +603,7 @@ let selectTypeWithSameHash (lst:IcdTypeAss list) =
| _ ->
lst |> List.minBy(
fun z ->
let (ReferenceToType nodes) = z.linkId;
let (ReferenceToType nodes) = z.typeId;
nodes.Length)


Expand Down Expand Up @@ -709,6 +709,10 @@ let printTasses3 stgFileName (r:DAst.AstRoot) : (string list)*(string list) =
| None -> ()
| false -> ()
} |> Seq.distinct |> Seq.toList
//print in a file the icds that are going to be printed
let content = icdHashesToPrint |> Seq.StrJoin "\n"
let fileName = sprintf "%s_icdHashesToPrint.txt" stgFileName
File.WriteAllText(fileName, content)
let files =
icdHashesToPrint
|> Seq.choose(fun hash ->
Expand Down Expand Up @@ -742,7 +746,8 @@ let PrintAsn1FileInColorizedHtml (stgFileName:string) (r:AstRoot) (icdHashesToPr
| true -> Some (z.name, z.hash)
| false -> None ) |>
Seq.distinct |>
Seq.toList
Seq.groupBy fst |>
Seq.map(fun (tasName, tasHashes) -> (tasName, tasHashes |> Seq.map snd |> List.ofSeq)) |> Map.ofSeq


//let blueTasses = f.Modules |> Seq.collect(fun m -> getModuleBlueTasses m)
Expand Down Expand Up @@ -774,6 +779,10 @@ let PrintAsn1FileInColorizedHtml (stgFileName:string) (r:AstRoot) (icdHashesToPr
let findToken = Array.tryFind(fun tok -> checkWsCmt tok)
let findNextToken = f.Tokens.[idx+1..] |> findToken
let findPrevToken = Array.rev f.Tokens.[0..idx-1] |> findToken

//let findNextToken = f.Tokens.[idx+1..] |> Array.tryFind(fun tok -> checkWsCmt tok)
//let findPrevToken = f.Tokens.[0..idx-1] |> Array.tryFindBack(fun tok -> checkWsCmt tok)

let nextToken =
let size = Seq.length(f.Tokens) - 1
match findNextToken with
Expand All @@ -783,22 +792,26 @@ let PrintAsn1FileInColorizedHtml (stgFileName:string) (r:AstRoot) (icdHashesToPr
match findPrevToken with
|Some(tok) -> tok
|None -> if idx = 0 then t else f.Tokens.[idx-1]
let tasfileTypeAssignments = fileTypeAssignments |> List.filter(fun (tasName,_) -> tasName = t.Text)
match tasfileTypeAssignments with
| [] -> safeText
| (_,tasHash)::[] ->
//let tasfileTypeAssignments = fileTypeAssignments |> List.filter(fun (tasName,_) -> tasName = t.Text)
//match tasfileTypeAssignments with
match fileTypeAssignments.TryFind t.Text with
| None -> safeText
| Some ([]) -> safeText
//| (_,tasHash)::[] ->
| Some (tasHash::[]) ->
if nextToken.Type = asn1Lexer.ASSIG_OP && prevToken.Type <> asn1Lexer.LID then
icd_uper.TasName stgFileName safeText tasHash
else
icd_uper.TasName2 stgFileName safeText tasHash
| _ ->
| Some tasHashList ->
let tasName = t.Text
let debug () =
printfn "Warning: %s is not unique. %d" t.Text tasfileTypeAssignments.Length
printfn "Warning: %s is not unique. %d" t.Text tasHashList.Length

printfn "Warning: %A" tasfileTypeAssignments
printfn "Warning: %A" tasHashList
//print to jso the type assignments that are not unique
tasfileTypeAssignments |>
Seq.iter (fun (tasName, tasHash) ->
tasHashList |>
Seq.iter (fun (tasHash) ->
let icdTas = r.icdHashes.[tasHash]
icdTas |>
Seq.iter(fun icdTas ->
Expand All @@ -809,7 +822,7 @@ let PrintAsn1FileInColorizedHtml (stgFileName:string) (r:AstRoot) (icdHashesToPr
//debug ()
safeText
//|None -> safeText
let colored =
let colored () =
match t.Type with
|asn1Lexer.StringLiteral
|asn1Lexer.OctectStringLiteral
Expand All @@ -820,28 +833,28 @@ let PrintAsn1FileInColorizedHtml (stgFileName:string) (r:AstRoot) (icdHashesToPr
|_ -> safeText
match blueTas with
|Some (s,_,_) -> icd_uper.BlueTas stgFileName (ToC s) safeText
|None -> if isAsn1Token then icd_uper.Asn1Token stgFileName safeText else colored
let asn1Content = f.Tokens |> Seq.mapi(fun i token -> colorize(token,i,blueTassesWithLoc))
icd_uper.EmitFilePart2 stgFileName (Path.GetFileName f.FileName ) (asn1Content |> Seq.StrJoin "")
|None -> if isAsn1Token then icd_uper.Asn1Token stgFileName safeText else (colored ())
let asn1Content = f.Tokens |> Seq.mapi(fun i token -> colorize(token,i,blueTassesWithLoc)) |> Seq.toList
icd_uper.EmitFilePart2 stgFileName (Path.GetFileName f.FileName ) (asn1Content )


let DoWork (r:AstRoot) (deps:Asn1AcnAst.AcnInsertedFieldDependencies) (stgFileName:string) (asn1HtmlStgFileMacros:string option) outFileName =
let files1 = r.Files |> Seq.map (fun f -> PrintTasses stgFileName f r )
let (files1b, icdHashesToPrint) = printTasses3 stgFileName r
let files1 = TL "GenerateAcnIcd_PrintTasses" (fun () -> r.Files |> List.map (fun f -> PrintTasses stgFileName f r ))
let (files1b, icdHashesToPrint) = TL "GenerateAcnIcd_printTasses3" (fun () -> printTasses3 stgFileName r)
let bAcnParamsMustBeExplained = true
let asn1HtmlMacros =
match asn1HtmlStgFileMacros with
| None -> stgFileName
| Some x -> x
let files2 = r.Files |> Seq.map (PrintAsn1FileInColorizedHtml asn1HtmlMacros r icdHashesToPrint)
let files3 = PrintAcnAsHTML2 stgFileName r icdHashesToPrint
let files2 = TL "GenerateAcnIcd_PrintAsn1FileInColorizedHtml" (fun () -> r.Files |> List.map (PrintAsn1FileInColorizedHtml asn1HtmlMacros r icdHashesToPrint))
let files3 = TL "GenerateAcnIcd_PrintAcnAsHTML2" (fun () -> PrintAcnAsHTML2 stgFileName r icdHashesToPrint)
let cssFileName = Path.ChangeExtension(outFileName, ".css")
let htmlContent = icd_acn.RootHtml stgFileName files1 files2 bAcnParamsMustBeExplained files3 (Path.GetFileName(cssFileName))
let htmlContentb = icd_acn.RootHtml stgFileName files1b files2 bAcnParamsMustBeExplained files3 (Path.GetFileName(cssFileName))
let htmlContent = TL "GenerateAcnIcd_RootHtml" (fun () -> icd_acn.RootHtml stgFileName files1 files2 bAcnParamsMustBeExplained files3 (Path.GetFileName(cssFileName)))
let htmlContentb = TL "GenerateAcnIcd_RootHtml_b" (fun () -> icd_acn.RootHtml stgFileName files1b files2 bAcnParamsMustBeExplained files3 (Path.GetFileName(cssFileName)))

File.WriteAllText(outFileName, htmlContent.Replace("\r",""))
File.WriteAllText(outFileName.Replace(".html", "_new.html"), htmlContentb.Replace("\r",""))
let cssFileName = Path.ChangeExtension(outFileName, ".css");
emitCss r stgFileName cssFileName
TL "GenerateAcnIcd_emitCss" (fun () -> emitCss r stgFileName cssFileName)


2 changes: 1 addition & 1 deletion BackendAst/GenerateUperIcd.fs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ let PrintFile2 (stgFileName:string) (f:Asn1File) =
|Some (s,_,_) -> icd_uper.BlueTas stgFileName (ToC s) safeText
|None -> if isAsn1Token then icd_uper.Asn1Token stgFileName safeText else colored
let asn1Content = f.Tokens |> Seq.mapi(fun i token -> colorize(token,i,tasNames,blueTassesWithLoc))
icd_uper.EmitFilePart2 stgFileName (Path.GetFileName f.FileName ) (asn1Content |> Seq.StrJoin "")
icd_uper.EmitFilePart2 stgFileName (Path.GetFileName f.FileName ) (asn1Content )

let DoWork (r:AstRoot) (stgFileName:string) outFileName =
let files1 = r.Files |> Seq.map (fun f -> PrintFile1 stgFileName f r )
Expand Down
Loading

0 comments on commit 55633c4

Please sign in to comment.