#!/usr/bin/env gbs3

Private $fCompileTime As Float

Private Sub RunScript(sScript As String, sRun As String, bGambasOnly As Boolean) As Float

  Dim aResult As String[]
  Dim sResult As String
  Dim fTime As Float
  Dim aTime As String[]

  If Not Exist(Application.Dir &/ sScript) Then Return -1
  
  If bGambasOnly Then
    Print "Running benchmark: '"; sRun; " "; sScript; "'"
  Else
    Print "<!-- Running benchmark: '"; sRun; " "; sScript; "' -->"
  Endif
  
  Shell "time " & sRun & " " & sScript & " > /dev/null" To sResult With Error
  If Not sResult Then Error.Raise("Script '" & sRun & " " & sScript & "' failed!")
  aResult = Split(sResult, "\n")
  For Each sResult In aResult
    sResult = Trim(sResult)
    If sResult Begins "user" Or If sResult Begins "sys" Then
      aTime = Split(Trim(Mid$(sResult, 5)), "ms", "", True)
      fTime += CFloat(aTime[0]) * 60 + CFloat(aTime[1])
    Endif
  Next
  
  $fCompileTime = 0
  Try $fCompileTime = CFloat(Trim(aResult[0]))
  
  Return fTime

End

Private Sub FormatResult(cResult As Collection, iCount As Integer, sLang As String) As String

  Dim bBetter As Boolean = True
  Dim sFormat As String
  Dim sTest As String

  If cResult[sLang] <= 0 Then Return Format("30", "0.00") & "+"

  For Each sTest In ["python", "perl", "java", "gambas"]
    If cResult[sTest] > 0 And If cResult[sTest] < cResult[sLang] Then
      bBetter = False
      Break
    Endif
  Next

  sFormat = Format(cResult[sLang] / iCount, "0.00")
  If bBetter Then sFormat = "<b>" & sFormat & "</b>"
  Return sFormat

End

Dim sBenchmark As String
Dim cResult As Collection
Dim cAllResult As New Collection
Dim sLang As String 
Dim sResult As String
Dim iPos As Integer
Dim bGambasOnly As Boolean
Dim sBenchmarkOnly As String
Dim iCount As Integer = 1
Dim I As Integer
Dim fTime As Float

System.Language = "C"
Env["GB_JIT_CACHE"] = "0"
Shell "rm -rf " & Shell$(Application.Dir &/ " __pycache__") Wait

For I = 1 To Args.Max

  If Args[I] = "-gambas" Then
    bGambasOnly = True
 Else If Args[I] = "-count" Then
  If I < Args.Max And If Args[I + 1] Not Begins "-" Then
    Try iCount = Max(1, CInt(Args[I + 1]))
   Inc I
  Endif
  Else
    sBenchmarkOnly = Args[I]
  Endif

Next

For I = 1 To iCount

  If iCount > 1 Then Print "-------- Run #"; I; " --------"

  For Each sBenchmark In Dir(Application.Dir, "*.gbs").Sort()

    sBenchmark = File.BaseName(sBenchmark)
    If sBenchmark = "benchmark" Then Continue
    If sBenchmarkOnly And If sBenchmark <> sBenchmarkOnly Then Continue

    cResult = cAllResult[sBenchmark]
    If Not cResult Then
    cResult = New Collection
    cResult.Default = 0.0
    cResult!name = sBenchmark
    cAllResult[sBenchmark] = cResult
    Endif
  
    If Not bGambasOnly Then
      If sBenchmark <> "string2" Then
        cResult!python += RunScript(sBenchmark & ".py", "python", bGambasOnly)
      Endif
      cResult!perl += RunScript(sBenchmark & ".pl", "perl", bGambasOnly)
      If sBenchmark Not Begins "string" Then
        cResult!java += RunScript(sBenchmark & ".jvs", "java -Xint --source 11", bGambasOnly)
      Endif
      cResult!javajit += RunScript(sBenchmark & ".jvs", "java --source 11", bGambasOnly)
    Endif

    fTime = RunScript(sBenchmark & ".gbs", "gbs3 -f -U -c", bGambasOnly)
    cResult!gambasjit += fTime
    cResult!gambasjitwct += fTime - $fCompileTime
    cResult!gambas += RunScript(sBenchmark & ".gbs", "gbs3 -c", bGambasOnly)

  Next
 
Next

Print

' Print "<div style=\"border:solid 1px gray;padding:8px;display:inline-table;background:\">"
' 
' Exec ["uname", "-srv"] To sResult
' Print "<b>Kernel:</b> ";Html(sResult);"<br>"
'
' Exec ["cat", "/proc/cpuinfo"] To sResult
' For Each sResult In Split(sResult, "\n")
'   If sResult Begins "model name" Then
'     iPos = Instr(sResult, ":")
'     If iPos Then
'       Print "<b>CPU:</b> ";Html(Mid$(sResult, iPos+1));"<br>"
'     Endif
'     Break
'   Endif
' Next
' 
' Print "</div>"

If bGambasOnly Then

  For Each cResult In cAllResult
    Print cResult!name; Space$(20 - Len(cResult!name)); ": "; Format(cResult!gambas / iCount, "0.00"); " / "; Format(cResult!gambasjit / iCount, "0.00"); " (jit)"; " / "; Format(cResult!gambasjitwct / iCount, "0.00"); " (jit without compilation time)"
  Next

Else

  Print "<table class=\"table\">"
  Print "<tr>\n<th>Benchmark</th>"
  For Each sLang In ["Python", "Perl", "Java", "Gambas", "Java JIT", "Gambas JIT", "Gambas JIT without compilation time"]
    Print "<th style=\"width:12em;\">"; Html(sLang); "</th>"
  Next
  Print "</tr>"
  For Each cResult In cAllResult
    Print "<tr>"
    Print "<td><tt>"; cResult!name; "</tt></td>"
    Print "<td align=\"right\">"; FormatResult(cResult, iCount, "python"); "&nbsp;</td>"
    Print "<td align=\"right\">"; FormatResult(cResult, iCount, "perl"); "&nbsp;</td>"
    Print "<td align=\"right\">"; FormatResult(cResult, iCount, "java"); "&nbsp;</td>"
    Print "<td align=\"right\">"; FormatResult(cResult, iCount, "gambas"); "&nbsp;</td>"
    Print "<td align=\"right\">"; Format(cResult!javajit / iCount, "0.00"); "&nbsp;</td>"
    Print "<td align=\"right\">"; Format(cResult!gambasjit / iCount, "0.00"); "&nbsp;</td>"
    Print "<td align=\"right\">"; Format(cResult!gambasjitwct / iCount, "0.00"); "&nbsp;</td>"
    Print "</tr>"
  Next
  Print "</table>"
  
Endif

