elixir-circuits / circuits_uart

Discover and use UARTs and serial ports in Elixir
Apache License 2.0
188 stars 48 forks source link

Performance slower than Python #28

Closed pallix closed 6 years ago

pallix commented 6 years ago

I am sending 1,1MB of data with this code:

  @buff_size 4000

  alias NervesUartEvaluation.Serial
  alias Nerves.UART

  def write(file) do
    serial = Serial.setup_serial(:writeDeviceName)
    write_loop(serial, file)
  end

  def write_loop(serial, file) do
    case IO.binread(file, @buff_size) do
      :eof -> UART.flush(serial); IO.puts "done"
      {:error, reason} -> IO.puts("Error" <> reason)
      content ->
        IO.puts(byte_size(content))
        UART.write(serial, content)
        UART.drain(serial)
        write_loop(serial, file)
    end
  end

and reading with cat. I observe a transmission rate of about 77 KiB/s (77 kilobyte/sec).

When doing the same experiment with PySerial, the transmission rate is of 88.7 KiB/s.

What can explain the performance drop? I would expect same speed as the test is IO bound.

fhunleth commented 6 years ago

Probably because no effort has gone into optimizing the library? I could guess at a few issues - OS process separation from the Erlang VM (for reliability) comes to mind, but I don't know. I'd certainly be happy to get PRs that improve performance, but since I'm barely doing 10 KiB/s (115200 baud) on any use of mine, I can't say that this is a priority for me.

pallix commented 6 years ago

Do you think the Erlang Port make the communication slower?

ConnorRigby commented 6 years ago

https://nmuth.svbtle.com/some-informal-benchmarks-on-language-interop-with-elixir-ports

@pallix Give that a read. Ports basically happen over stdin/stdout.