benchmark.pp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. (*
  2. This file is part of libmicrohttpd
  3. Copyright (C) 2007, 2013 Christian Grothoff (and other contributing authors)
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  15. *)
  16. (**
  17. * @file benchmark.pp (Original: benchmark.c)
  18. * @brief minimal code to benchmark MHD GET performance
  19. * @author Christian Grothoff / Silvio Clécio
  20. *)
  21. program benchmark;
  22. {$mode objfpc}{$H+}
  23. {$MACRO ON}
  24. {$IF DEFINED(CPU_COUNT) and (CPU_COUNT + 0) < 2}
  25. {$UNDEF CPU_COUNT}
  26. {$ENDIF}
  27. {$IF NOT DEFINED(CPU_COUNT)}
  28. {$DEFINE CPU_COUNT := 2}
  29. {$ENDIF}
  30. uses
  31. {$IFDEF MSWINDOWS}
  32. WinSock2,
  33. {$ELSE}
  34. BaseUnix, Unix,
  35. {$ENDIF}
  36. cmem, sysutils, cutils, libmicrohttpd;
  37. const
  38. PAGE: Pcchar = '<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>';
  39. SMALL = 1024 * 128;
  40. NUMBER_OF_THREADS = CPU_COUNT;
  41. var
  42. small_deltas: array[0..SMALL] of cuint;
  43. response: PMHD_Response;
  44. procedure completed_callback(cls: Pointer; connection: PMHD_Connection;
  45. con_cls: PPointer; toe: MHD_RequestTerminationCode); cdecl;
  46. var
  47. tv: ptimeval;
  48. tve: timeval;
  49. delta: cuint64;
  50. begin
  51. tv := con_cls^;
  52. if nil = tv then
  53. Exit;
  54. fpgettimeofday(@tve, nil);
  55. delta := 0;
  56. if tve.tv_usec >= tv^.tv_usec then
  57. delta += (tve.tv_sec - tv^.tv_sec) * 1000000 +
  58. (tve.tv_usec - tv^.tv_usec)
  59. else
  60. delta += (tve.tv_sec - tv^.tv_sec) * 1000000 -
  61. tv^.tv_usec + tve.tv_usec;
  62. if delta < SMALL then
  63. Inc(small_deltas[delta])
  64. else
  65. WriteLn(stdout, Format('D: %u 1', [delta]));
  66. Free(tv);
  67. end;
  68. function uri_logger_cb(cls: Pointer; uri: Pcchar): Pointer; cdecl;
  69. var
  70. tv: ptimeval;
  71. begin
  72. tv := Malloc(SizeOf(timeval));
  73. if nil <> tv then
  74. fpgettimeofday(tv, nil);
  75. Result := tv;
  76. end;
  77. function ahc_echo(cls: Pointer; connection: PMHD_Connection; url: Pcchar;
  78. method: Pcchar; version: Pcchar; upload_data: Pcchar;
  79. upload_data_size: Psize_t; ptr: PPointer): cint; cdecl;
  80. begin
  81. if 0 <> strcomp(method, 'GET') then
  82. Exit(MHD_NO);
  83. Result := MHD_queue_response(connection, MHD_HTTP_OK, response);
  84. end;
  85. var
  86. d: PMHD_Daemon;
  87. i: cuint;
  88. begin
  89. if argc <> 2 then
  90. begin
  91. WriteLn(argv[0] + ' PORT');
  92. Halt(1);
  93. end;
  94. response := MHD_create_response_from_buffer(Length(PAGE), Pointer(PAGE),
  95. MHD_RESPMEM_PERSISTENT);
  96. {$IF 0}
  97. MHD_add_response_header (response, MHD_HTTP_HEADER_CONNECTION, 'close');
  98. {$ENDIF}
  99. d := MHD_start_daemon(MHD_USE_SELECT_INTERNALLY or MHD_SUPPRESS_DATE_NO_CLOCK
  100. {$IFDEF EPOLL_SUPPORT}
  101. or MHD_USE_EPOLL_LINUX_ONLY or MHD_USE_EPOLL_TURBO
  102. {$ENDIF},
  103. StrToInt(argv[1]), nil, nil, @ahc_echo, nil,
  104. MHD_OPTION_CONNECTION_TIMEOUT, 120,
  105. MHD_OPTION_THREAD_POOL_SIZE, NUMBER_OF_THREADS,
  106. MHD_OPTION_URI_LOG_CALLBACK, @uri_logger_cb, nil,
  107. MHD_OPTION_NOTIFY_COMPLETED, @completed_callback, nil,
  108. MHD_OPTION_CONNECTION_LIMIT, 1000,
  109. MHD_OPTION_END);
  110. if d = nil then
  111. Halt(1);
  112. ReadLn;
  113. MHD_stop_daemon(d);
  114. MHD_destroy_response(response);
  115. for i := 0 to SMALL do
  116. if 0 <> small_deltas[i] then
  117. WriteLn(stdout, Format('D: %d %u', [i, small_deltas[i]]));
  118. end.