3 people like it.
Like the snippet!
Simple Redis F# Client Test
Simple Redis F# Client Test
(Async version will stop respond when data are too large. Don't know how to solve yet.)
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
|
open System
open System.Net.Sockets
open System.Text
type RedisClient () =
// Socket
let clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
do clientSocket.Connect("127.0.0.1", 6379)
let netStream = new NetworkStream(clientSocket, true)
// Helper
let toS (o:obj) = Convert.ToString(o)
let toC (o:obj) = Convert.ToChar(o)
let getBytes (s:string) = Encoding.UTF8.GetBytes(s)
let getString (b:byte[]) = Encoding.UTF8.GetString(b)
let mergeCommand (l:list<String>) =
let sb = new StringBuilder()
sb.Append("*" + toS l.Length + "\r\n") |> ignore
l |> List.iter (fun item -> sb.Append("$" + toS item.Length + "\r\n") |> ignore
sb.Append(toS item + "\r\n") |> ignore )
getBytes <| sb.ToString()
// Member
member x.AsyncSend l = async { let b = mergeCommand l
do! netStream.AsyncWrite(b, 0, b.Length) }
member x.SyncSend l = let b = mergeCommand l
netStream.Write(b, 0, b.Length)
member x.ReadLine () = let n = ref 0
let sb = new StringBuilder()
while !n <> 10 do
n := netStream.ReadByte()
if !n <> 13 && !n <> 10 then sb.Append(toC !n) |> ignore
sb.ToString()
member x.Close () = netStream.Close()
// Test Helper
let values m = List.concat [for i in 1 .. m -> ["K" + i.ToString(); "V" + i.ToString()] ]
// ["K1";"V1";"K2";"V2";"K3";"V3"; ... ]
let SyncTest n v = [ for i in 1 .. n ->
async {
let r = new RedisClient()
r.SyncSend("MSET" :: v)
let s = r.ReadLine()
r.Close()
return s }] |> Async.Parallel |> Async.RunSynchronously
let AsyncTest n v = [ for i in 1 .. n ->
async {
let r = new RedisClient()
do! r.AsyncSend("MSET" :: v)
let s = r.ReadLine()
r.Close()
return s }] |> Async.Parallel |> Async.RunSynchronously
let RealSync n v = [ for i in 1 .. n ->
let r = new RedisClient()
r.SyncSend("MSET" :: v)
let s = r.ReadLine()
r.Close()
s ]
// Test
#time
let shortValues = values 100
let longValues = values 2000
SyncTest 3000 shortValues
AsyncTest 3000 shortValues
RealSync 3000 shortValues
SyncTest 3000 longValues
AsyncTest 3000 longValues // Async version will stop respond when data are too large.
// Don't know how to solve yet.
RealSync 3000 longValues
|
namespace System
namespace System.Net
namespace System.Net.Sockets
namespace System.Text
Multiple items
type RedisClient =
new : unit -> RedisClient
member AsyncSend : l:String list -> Async<unit>
member Close : unit -> unit
member ReadLine : unit -> string
member SyncSend : l:String list -> unit
Full name: Script.RedisClient
--------------------
new : unit -> RedisClient
val clientSocket : Socket
Multiple items
type Socket =
new : socketInformation:SocketInformation -> Socket + 1 overload
member Accept : unit -> Socket
member AcceptAsync : e:SocketAsyncEventArgs -> bool
member AddressFamily : AddressFamily
member Available : int
member BeginAccept : callback:AsyncCallback * state:obj -> IAsyncResult + 2 overloads
member BeginConnect : remoteEP:EndPoint * callback:AsyncCallback * state:obj -> IAsyncResult + 3 overloads
member BeginDisconnect : reuseSocket:bool * callback:AsyncCallback * state:obj -> IAsyncResult
member BeginReceive : buffers:IList<ArraySegment<byte>> * socketFlags:SocketFlags * callback:AsyncCallback * state:obj -> IAsyncResult + 3 overloads
member BeginReceiveFrom : buffer:byte[] * offset:int * size:int * socketFlags:SocketFlags * remoteEP:EndPoint * callback:AsyncCallback * state:obj -> IAsyncResult
...
Full name: System.Net.Sockets.Socket
--------------------
Socket(socketInformation: SocketInformation) : unit
Socket(addressFamily: AddressFamily, socketType: SocketType, protocolType: ProtocolType) : unit
type AddressFamily =
| Unknown = -1
| Unspecified = 0
| Unix = 1
| InterNetwork = 2
| ImpLink = 3
| Pup = 4
| Chaos = 5
| NS = 6
| Ipx = 6
| Iso = 7
...
Full name: System.Net.Sockets.AddressFamily
field AddressFamily.InterNetwork = 2
type SocketType =
| Stream = 1
| Dgram = 2
| Raw = 3
| Rdm = 4
| Seqpacket = 5
| Unknown = -1
Full name: System.Net.Sockets.SocketType
field SocketType.Stream = 1
type ProtocolType =
| IP = 0
| IPv6HopByHopOptions = 0
| Icmp = 1
| Igmp = 2
| Ggp = 3
| IPv4 = 4
| Tcp = 6
| Pup = 12
| Udp = 17
| Idp = 22
...
Full name: System.Net.Sockets.ProtocolType
field ProtocolType.Tcp = 6
Socket.Connect(remoteEP: Net.EndPoint) : unit
Socket.Connect(addresses: Net.IPAddress [], port: int) : unit
Socket.Connect(host: string, port: int) : unit
Socket.Connect(address: Net.IPAddress, port: int) : unit
val netStream : NetworkStream
Multiple items
type NetworkStream =
inherit Stream
new : socket:Socket -> NetworkStream + 3 overloads
member BeginRead : buffer:byte[] * offset:int * size:int * callback:AsyncCallback * state:obj -> IAsyncResult
member BeginWrite : buffer:byte[] * offset:int * size:int * callback:AsyncCallback * state:obj -> IAsyncResult
member CanRead : bool
member CanSeek : bool
member CanTimeout : bool
member CanWrite : bool
member Close : timeout:int -> unit
member DataAvailable : bool
member EndRead : asyncResult:IAsyncResult -> int
...
Full name: System.Net.Sockets.NetworkStream
--------------------
NetworkStream(socket: Socket) : unit
NetworkStream(socket: Socket, ownsSocket: bool) : unit
NetworkStream(socket: Socket, access: IO.FileAccess) : unit
NetworkStream(socket: Socket, access: IO.FileAccess, ownsSocket: bool) : unit
val toS : (obj -> string)
val o : obj
type obj = Object
Full name: Microsoft.FSharp.Core.obj
type Convert =
static val DBNull : obj
static member ChangeType : value:obj * typeCode:TypeCode -> obj + 3 overloads
static member FromBase64CharArray : inArray:char[] * offset:int * length:int -> byte[]
static member FromBase64String : s:string -> byte[]
static member GetTypeCode : value:obj -> TypeCode
static member IsDBNull : value:obj -> bool
static member ToBase64CharArray : inArray:byte[] * offsetIn:int * length:int * outArray:char[] * offsetOut:int -> int + 1 overload
static member ToBase64String : inArray:byte[] -> string + 3 overloads
static member ToBoolean : value:obj -> bool + 17 overloads
static member ToByte : value:obj -> byte + 18 overloads
...
Full name: System.Convert
Convert.ToString(value: string) : string
(+0 other overloads)
Convert.ToString(value: DateTime) : string
(+0 other overloads)
Convert.ToString(value: decimal) : string
(+0 other overloads)
Convert.ToString(value: float) : string
(+0 other overloads)
Convert.ToString(value: float32) : string
(+0 other overloads)
Convert.ToString(value: uint64) : string
(+0 other overloads)
Convert.ToString(value: int64) : string
(+0 other overloads)
Convert.ToString(value: uint32) : string
(+0 other overloads)
Convert.ToString(value: int) : string
(+0 other overloads)
Convert.ToString(value: uint16) : string
(+0 other overloads)
val toC : (obj -> char)
Convert.ToChar(value: DateTime) : char
(+0 other overloads)
Convert.ToChar(value: decimal) : char
(+0 other overloads)
Convert.ToChar(value: float) : char
(+0 other overloads)
Convert.ToChar(value: float32) : char
(+0 other overloads)
Convert.ToChar(value: string) : char
(+0 other overloads)
Convert.ToChar(value: uint64) : char
(+0 other overloads)
Convert.ToChar(value: int64) : char
(+0 other overloads)
Convert.ToChar(value: uint32) : char
(+0 other overloads)
Convert.ToChar(value: int) : char
(+0 other overloads)
Convert.ToChar(value: uint16) : char
(+0 other overloads)
val getBytes : (string -> byte [])
val s : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
type Encoding =
member BodyName : string
member Clone : unit -> obj
member CodePage : int
member DecoderFallback : DecoderFallback with get, set
member EncoderFallback : EncoderFallback with get, set
member EncodingName : string
member Equals : value:obj -> bool
member GetByteCount : chars:char[] -> int + 3 overloads
member GetBytes : chars:char[] -> byte[] + 5 overloads
member GetCharCount : bytes:byte[] -> int + 2 overloads
...
Full name: System.Text.Encoding
property Encoding.UTF8: Encoding
Encoding.GetBytes(s: string) : byte []
Encoding.GetBytes(chars: char []) : byte []
Encoding.GetBytes(chars: char [], index: int, count: int) : byte []
Encoding.GetBytes(chars: nativeptr<char>, charCount: int, bytes: nativeptr<byte>, byteCount: int) : int
Encoding.GetBytes(s: string, charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
Encoding.GetBytes(chars: char [], charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
val getString : (byte [] -> string)
val b : byte []
Multiple items
val byte : value:'T -> byte (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.byte
--------------------
type byte = Byte
Full name: Microsoft.FSharp.Core.byte
Encoding.GetString(bytes: byte []) : string
Encoding.GetString(bytes: byte [], index: int, count: int) : string
val mergeCommand : (String list -> byte [])
val l : String list
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Encoding) : unit
val sb : StringBuilder
Multiple items
type StringBuilder =
new : unit -> StringBuilder + 5 overloads
member Append : value:string -> StringBuilder + 18 overloads
member AppendFormat : format:string * arg0:obj -> StringBuilder + 4 overloads
member AppendLine : unit -> StringBuilder + 1 overload
member Capacity : int with get, set
member Chars : int -> char with get, set
member Clear : unit -> StringBuilder
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EnsureCapacity : capacity:int -> int
member Equals : sb:StringBuilder -> bool
...
Full name: System.Text.StringBuilder
--------------------
StringBuilder() : unit
StringBuilder(capacity: int) : unit
StringBuilder(value: string) : unit
StringBuilder(value: string, capacity: int) : unit
StringBuilder(capacity: int, maxCapacity: int) : unit
StringBuilder(value: string, startIndex: int, length: int, capacity: int) : unit
StringBuilder.Append(value: char []) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: obj) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: uint64) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: uint32) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: uint16) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: decimal) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: float) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: float32) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: int64) : StringBuilder
(+0 other overloads)
StringBuilder.Append(value: int) : StringBuilder
(+0 other overloads)
property List.Length: int
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
val iter : action:('T -> unit) -> list:'T list -> unit
Full name: Microsoft.FSharp.Collections.List.iter
val item : String
property String.Length: int
StringBuilder.ToString() : string
StringBuilder.ToString(startIndex: int, length: int) : string
val x : RedisClient
member RedisClient.AsyncSend : l:String list -> Async<unit>
Full name: Script.RedisClient.AsyncSend
val async : AsyncBuilder
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
member IO.Stream.AsyncWrite : buffer:byte [] * ?offset:int * ?count:int -> Async<unit>
property Array.Length: int
member RedisClient.SyncSend : l:String list -> unit
Full name: Script.RedisClient.SyncSend
NetworkStream.Write(buffer: byte [], offset: int, size: int) : unit
member RedisClient.ReadLine : unit -> string
Full name: Script.RedisClient.ReadLine
val n : int ref
Multiple items
val ref : value:'T -> 'T ref
Full name: Microsoft.FSharp.Core.Operators.ref
--------------------
type 'T ref = Ref<'T>
Full name: Microsoft.FSharp.Core.ref<_>
IO.Stream.ReadByte() : int
member RedisClient.Close : unit -> unit
Full name: Script.RedisClient.Close
IO.Stream.Close() : unit
NetworkStream.Close(timeout: int) : unit
val values : m:int -> string list
Full name: Script.values
val m : int
val concat : lists:seq<'T list> -> 'T list
Full name: Microsoft.FSharp.Collections.List.concat
val i : int
Int32.ToString() : string
Int32.ToString(provider: IFormatProvider) : string
Int32.ToString(format: string) : string
Int32.ToString(format: string, provider: IFormatProvider) : string
val SyncTest : n:int -> v:String list -> string []
Full name: Script.SyncTest
val n : int
val v : String list
val r : RedisClient
member RedisClient.SyncSend : l:String list -> unit
member RedisClient.ReadLine : unit -> string
member RedisClient.Close : unit -> unit
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken
Full name: Microsoft.FSharp.Control.Async
--------------------
type Async<'T>
Full name: Microsoft.FSharp.Control.Async<_>
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
val AsyncTest : n:int -> v:String list -> string []
Full name: Script.AsyncTest
member RedisClient.AsyncSend : l:String list -> Async<unit>
val RealSync : n:int -> v:String list -> string list
Full name: Script.RealSync
val shortValues : string list
Full name: Script.shortValues
val longValues : string list
Full name: Script.longValues
More information