Skip to content
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

How to improve performance? #61

Closed
throwaway4rust opened this issue Nov 3, 2020 · 3 comments
Closed

How to improve performance? #61

throwaway4rust opened this issue Nov 3, 2020 · 3 comments

Comments

@throwaway4rust
Copy link

import winim/lean
import strformat except `&`

proc main =
  var sc = OpenSCManager(nil, nil, SC_MANAGER_ENUMERATE_SERVICE)

  if sc != 0:
    defer: CloseServiceHandle(sc)

    const
      srvType = SERVICE_WIN32
      srvState = SERVICE_STATE_ALL

    var bytesNeeded, srvCount, resumeHandle: DWORD

    # Use nil pointer in first call to avoid realloc the buffer later
    EnumServicesStatus(sc, srvType, srvState, nil, 0, &bytesNeeded, &srvCount,
      &resumeHandle)

    # Use string for the buffer, or you can use alloc() and then dealloc() later.
    var buffer = newString(bytesNeeded)

    # Cast the pointer to what EnumServicesStatus want.
    # Here &buffer = addr buffer[0]
    let lpService = cast[LPENUM_SERVICE_STATUS](&buffer)

    # We can access the low level c array easily by using Nim's UncheckedArray.
    let services = cast[ptr UncheckedArray[ENUM_SERVICE_STATUS]](lpService)

    EnumServicesStatus(sc, srvType, srvState, lpService, bytesNeeded,
      &bytesNeeded, &srvCount, &resumeHandle)

    echo fmt"Count of NT Services using EnumServicesStatus: {srvCount}"
    for i in 0..<srvCount:
      echo fmt"{services[i].lpServiceName}: {services[i].lpDisplayName}"

when isMainModule:
  main()

The following code when compiled with nim c -d:danger -d:release --gc:arc and tested with

Measure-Command { main.exe }

Takes 18ms on my machine.

Measure-Command { get-service }

Takes 3ms.

Is there any reason why or does anyone know how to improve performance?

@khchen
Copy link
Owner

khchen commented Nov 3, 2020

For other program, you may try adding --opt:speed and --passc:-flto. For this program, I don't think it can be improved anymore. Because I get the same result (about 20ms) if I comment out all the lines (compile an empty file).

@throwaway4rust
Copy link
Author

Maybe powershell get-service is using some pre-allocation strategy to do only 1 call?
It seems odd that powershell commandlet can beat low level code like this and also by providing more output than the Nim code above.

BTW if you feel like this is not worth discussing if we simply do not know and cant find out feel free to close the issue 👍
Thanks a lot for winim it's really an amazing library!

@throwaway4rust
Copy link
Author

measure-command { get-service | out-default }

Is the correct way to measure this commandlet as by default it's not measuring printing out on stdout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants