Description
I am seeing some performance issues and would like to ask others to take my test code and see if they have the same problem. Mostly, this is because I am running this against an SFTP server that I don't control or have any knowledge about, it's "black box" to me. So I want to make sure it's not that.
After noticing I wasn't getting the speeds I expected (sometimes as little as half) I wrote some code that gives a head to head comparison of speeds between SSH.NET and WinSCP. I used NuGet to get the latest versions of both SSH.NET and WinSCP. Testing file is an 834KB file.
Using VS 2015
Code build is targeted on .NET Framework 4.5.2
OS is Windows 10 (dev machine) and Windows Server 2012 R2 (test machine)
SSH.NET version, 2016.0.0
WinSCP version, 5.9.2
SFTP server reports it is: SSH-2.0-WS_FTP-SSH_7.6.3
Test Code:
using Renci.SshNet;
using System;
using System.Diagnostics;
using System.IO;
using WinSCP;
namespace SFTP_Compare {
class Program {
static string strServer = "xxxx";
static string strUser = "xxxx";
static string strPass = "xxxx";
static string strHostKey = "ssh-rsa 1024 xxxxxx";
static string strRmPath = "/home/";
static string strLcPath = "C:\\Data\\";
static string strFile = "test_file.xyz";
static int intPort = 22;
static void TestWinSCP(int pintLoops) {
long lngByteKnt = 0;
double dblCreated, dblConnected, dblOpenStream, dblDownloaded, dblEndTime;
double dblKBKntTotal = 0.0, dblCreatedTotal = 0.0, dblConnectedTotal = 0.0, dblOpenStreamTotal = 0.0, dblDownloadedTotal = 0.0, dblEndTimeTotal = 0.0;
Stopwatch swTimer = new Stopwatch();
Console.WriteLine();
Console.WriteLine("WinSCP download test, {0} iteration(s).", pintLoops);
Console.WriteLine("___________________________________________________________________");
Console.WriteLine("| Run | Client Cr | Connection | Download | Delete |");
for (int i = 0; i < pintLoops; i++) {
try {
swTimer.Start();
SessionOptions soptSettings = new SessionOptions();
soptSettings.Protocol = Protocol.Sftp;
soptSettings.HostName = strServer;
soptSettings.UserName = strUser;
soptSettings.Password = strPass;
soptSettings.SshHostKeyFingerprint = strHostKey;
using (WinSCP.Session sesConnection = new WinSCP.Session()) {
swTimer.Stop();
dblCreated = swTimer.Elapsed.TotalMilliseconds;
swTimer.Restart();
sesConnection.Open(soptSettings);
swTimer.Stop();
dblConnected = swTimer.Elapsed.TotalMilliseconds;
swTimer.Restart();
dblOpenStream = 0;
TransferOptions toptStreamSettings = new TransferOptions();
toptStreamSettings.TransferMode = TransferMode.Binary;
sesConnection.GetFiles(strRmPath + strFile, strLcPath + strFile, false, toptStreamSettings);
swTimer.Stop();
dblDownloaded = swTimer.Elapsed.TotalMilliseconds;
FileInfo fiFile = new FileInfo(strLcPath + strFile);
lngByteKnt = fiFile.Length;
swTimer.Restart();
}
File.Delete(strLcPath + strFile); // Delete local copy for next run...WRG
swTimer.Stop();
dblEndTime = swTimer.Elapsed.TotalMilliseconds;
// Output test results...WRG
Console.WriteLine("|{0,4} |{1,8:N1} ms |{2,10:N1} ms |{3,12:N1} ms |{4,8:N1} ms |", i + 1, dblCreated, dblConnected, dblDownloaded, dblEndTime);
// Save totals for later...WRG
dblKBKntTotal += (lngByteKnt / 1024);
dblCreatedTotal += dblCreated;
dblConnectedTotal += dblConnected;
dblOpenStreamTotal += dblOpenStream;
dblDownloadedTotal += (dblDownloaded);
dblEndTimeTotal += dblEndTime;
} catch (Exception ex) {
Console.WriteLine(" *** Error on run {0}, Message: {1}", i + 1, ex.Message);
}
}
Console.WriteLine("|=======|============|==============|================|============|");
Console.WriteLine("| avg |{0,8:N1} ms |{1,10:N1} ms |{2,12:N1} ms |{3,8:N1} ms |", (dblCreatedTotal / pintLoops), (dblConnectedTotal / pintLoops), (dblDownloadedTotal / pintLoops), (dblEndTimeTotal / pintLoops));
Console.WriteLine("|_______|____________|______________|________________|____________|");
Console.WriteLine(" *** Average download speed for {0:N0} bytes: {1,5:N2} KB/s", (dblKBKntTotal * 1024), (dblKBKntTotal / (dblDownloadedTotal / 1000)));
Console.WriteLine();
}
static void TestSSHNET(int pintLoops) {
long lngByteKnt = 0;
double dblCreated, dblConnected, dblOpenStream, dblDownloaded, dblEndTime;
double dblKBKntTotal = 0.0, dblCreatedTotal = 0.0, dblConnectedTotal = 0.0, dblOpenStreamTotal = 0.0, dblDownloadedTotal = 0.0, dblEndTimeTotal = 0.0;
Stopwatch swTimer = new Stopwatch();
Console.WriteLine();
Console.WriteLine("SSH.NET download test, {0} iteration(s).", pintLoops);
Console.WriteLine("___________________________________________________________________");
Console.WriteLine("| Run | Client Cr | Connection | Download | Delete |");
for (int i = 0; i < pintLoops; i++) {
try {
swTimer.Start();
using (SftpClient sftpClient = new SftpClient(strServer, intPort, strUser, strPass)) {
swTimer.Stop();
dblCreated = swTimer.Elapsed.TotalMilliseconds;
swTimer.Restart();
sftpClient.Connect();
swTimer.Stop();
dblConnected = swTimer.Elapsed.TotalMilliseconds;
swTimer.Restart();
using (Stream sFile = File.Open(strLcPath + strFile, FileMode.Create, FileAccess.Write)) {
dblOpenStream = 0;
//swTimer.Stop();
//dblOpenStream = swTimer.Elapsed.TotalMilliseconds;
//swTimer.Restart();
sftpClient.DownloadFile(strRmPath + strFile, sFile);
swTimer.Stop();
dblDownloaded = swTimer.Elapsed.TotalMilliseconds;
lngByteKnt = sFile.Length;
swTimer.Restart();
}
}
File.Delete(strLcPath + strFile); // Delete local copy for next run...WRG
swTimer.Stop();
dblEndTime = swTimer.Elapsed.TotalMilliseconds;
// Output test results...WRG
Console.WriteLine("|{0,4} |{1,8:N1} ms |{2,10:N1} ms |{3,12:N1} ms |{4,8:N1} ms |", i+1, dblCreated, dblConnected, dblDownloaded, dblEndTime);
// Save totals for later...WRG
dblKBKntTotal += (lngByteKnt/1024);
dblCreatedTotal += dblCreated;
dblConnectedTotal += dblConnected;
dblOpenStreamTotal += dblOpenStream;
dblDownloadedTotal += (dblDownloaded);
dblEndTimeTotal += dblEndTime;
} catch (Exception ex) {
Console.WriteLine(" *** Error on run {0}, Message: {1}", i+1, ex.Message);
}
}
Console.WriteLine("|=======|============|==============|================|============|");
Console.WriteLine("| avg |{0,8:N1} ms |{1,10:N1} ms |{2,12:N1} ms |{3,8:N1} ms |", (dblCreatedTotal / pintLoops), (dblConnectedTotal / pintLoops), (dblDownloadedTotal / pintLoops), (dblEndTimeTotal / pintLoops));
Console.WriteLine("|_______|____________|______________|________________|____________|");
Console.WriteLine(" *** Average download speed for {0:N0} bytes: {1,5:N2} KB/s", (dblKBKntTotal * 1024), (dblKBKntTotal / (dblDownloadedTotal / 1000)));
Console.WriteLine();
}
static void Main(string[] args) {
TestWinSCP(50);
TestSSHNET(50);
}
}
}
Output from command prompt session on test machine:
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
C:\Windows\system32>cd C:\Data
C:\Data>dir
Volume in drive C has no label.
Volume Serial Number is E6AE-D23F
Directory of C:\Data
10/11/2016 01:03 PM <DIR> .
10/11/2016 01:03 PM <DIR> ..
10/06/2016 07:21 PM 408,064 Renci.SshNet.dll
10/06/2016 07:21 PM 961,463 Renci.SshNet.xml
10/11/2016 01:02 PM 9,216 SFTP_Compare.exe
10/06/2016 07:18 PM 189 SFTP_Compare.exe.config
10/11/2016 01:02 PM 15,872 SFTP_Compare.pdb
10/10/2016 03:03 PM 22,696 SFTP_Compare.vshost.exe
10/06/2016 07:18 PM 189 SFTP_Compare.vshost.exe.config
07/10/2015 07:01 AM 490 SFTP_Compare.vshost.exe.manifest
10/06/2016 07:22 PM 18,886,048 WinSCP.exe
10/08/2016 02:48 PM 75 winscp.ini
10/06/2016 07:22 PM 149,584 WinSCPnet.dll
11 File(s) 20,453,886 bytes
2 Dir(s) 16,536,723,456 bytes free
C:\Data>sftp_compare
WinSCP download test, 50 iteration(s).
___________________________________________________________________
| Run | Client Cr | Connection | Download | Delete |
| 1 | 4.2 ms | 1,797.8 ms | 781.9 ms | 110.5 ms |
| 2 | 110.6 ms | 1,778.7 ms | 843.9 ms | 110.3 ms |
| 3 | 110.4 ms | 1,779.8 ms | 843.7 ms | 110.4 ms |
| 4 | 110.4 ms | 1,779.9 ms | 843.8 ms | 110.4 ms |
| 5 | 110.4 ms | 1,779.9 ms | 843.8 ms | 110.5 ms |
| 6 | 110.5 ms | 1,779.8 ms | 843.7 ms | 110.3 ms |
| 7 | 110.4 ms | 1,780.0 ms | 843.8 ms | 110.3 ms |
| 8 | 110.3 ms | 2,592.7 ms | 843.8 ms | 110.6 ms |
| 9 | 110.7 ms | 2,582.1 ms | 843.6 ms | 110.2 ms |
| 10 | 110.3 ms | 1,782.1 ms | 1,656.3 ms | 110.6 ms |
| 11 | 110.7 ms | 1,779.4 ms | 843.9 ms | 110.4 ms |
| 12 | 110.4 ms | 2,592.2 ms | 843.8 ms | 110.5 ms |
| 13 | 110.6 ms | 1,779.7 ms | 843.9 ms | 110.6 ms |
| 14 | 110.7 ms | 1,779.4 ms | 1,656.4 ms | 110.2 ms |
| 15 | 110.3 ms | 2,592.3 ms | 843.7 ms | 110.6 ms |
| 16 | 110.7 ms | 2,592.1 ms | 843.9 ms | 110.2 ms |
| 17 | 110.3 ms | 1,779.9 ms | 843.8 ms | 110.6 ms |
| 18 | 110.7 ms | 1,779.7 ms | 843.8 ms | 110.6 ms |
| 19 | 110.7 ms | 2,591.9 ms | 843.9 ms | 110.4 ms |
| 20 | 110.5 ms | 1,779.5 ms | 846.6 ms | 110.5 ms |
| 21 | 110.5 ms | 2,593.7 ms | 844.8 ms | 110.2 ms |
| 22 | 110.3 ms | 1,780.0 ms | 843.7 ms | 113.8 ms |
| 23 | 113.9 ms | 2,590.6 ms | 843.8 ms | 110.5 ms |
| 24 | 110.6 ms | 2,582.5 ms | 843.7 ms | 110.6 ms |
| 25 | 110.7 ms | 1,780.0 ms | 843.8 ms | 110.6 ms |
| 26 | 110.6 ms | 1,779.7 ms | 843.8 ms | 110.4 ms |
| 27 | 110.5 ms | 2,592.1 ms | 843.9 ms | 110.2 ms |
| 28 | 110.2 ms | 1,780.8 ms | 1,656.3 ms | 110.3 ms |
| 29 | 110.4 ms | 1,779.8 ms | 843.9 ms | 110.5 ms |
| 30 | 110.5 ms | 1,779.8 ms | 843.7 ms | 110.6 ms |
| 31 | 110.7 ms | 1,779.6 ms | 843.9 ms | 110.7 ms |
| 32 | 110.8 ms | 1,779.1 ms | 843.9 ms | 110.5 ms |
| 33 | 110.6 ms | 2,592.0 ms | 843.7 ms | 111.1 ms |
| 34 | 111.2 ms | 2,592.5 ms | 843.8 ms | 110.0 ms |
| 35 | 110.1 ms | 1,781.4 ms | 843.6 ms | 110.4 ms |
| 36 | 110.5 ms | 2,592.9 ms | 843.8 ms | 110.2 ms |
| 37 | 110.3 ms | 1,780.0 ms | 843.7 ms | 110.2 ms |
| 38 | 110.3 ms | 1,776.1 ms | 843.7 ms | 110.6 ms |
| 39 | 110.7 ms | 2,592.2 ms | 843.7 ms | 110.3 ms |
| 40 | 110.4 ms | 1,780.0 ms | 843.7 ms | 110.4 ms |
| 41 | 110.4 ms | 2,592.9 ms | 843.8 ms | 110.3 ms |
| 42 | 110.3 ms | 1,780.4 ms | 843.9 ms | 110.4 ms |
| 43 | 110.5 ms | 2,592.2 ms | 843.8 ms | 110.5 ms |
| 44 | 110.6 ms | 2,592.3 ms | 843.7 ms | 102.5 ms |
| 45 | 102.6 ms | 1,779.5 ms | 843.7 ms | 110.3 ms |
| 46 | 110.4 ms | 2,593.1 ms | 1,657.7 ms | 110.3 ms |
| 47 | 110.4 ms | 1,779.6 ms | 843.8 ms | 110.5 ms |
| 48 | 110.6 ms | 2,582.8 ms | 843.8 ms | 110.1 ms |
| 49 | 110.2 ms | 1,779.6 ms | 843.7 ms | 110.3 ms |
| 50 | 110.4 ms | 1,781.4 ms | 843.8 ms | 110.5 ms |
|=======|============|==============|================|============|
| avg | 108.3 ms | 2,088.4 ms | 907.7 ms | 110.3 ms |
|_______|____________|______________|________________|____________|
*** Average download speed for 42,700,800 bytes: 918.86 KB/s
SSH.NET download test, 50 iteration(s).
___________________________________________________________________
| Run | Client Cr | Connection | Download | Delete |
| 1 | 11.3 ms | 974.3 ms | 1,337.5 ms | 190.6 ms |
| 2 | 190.6 ms | 815.4 ms | 1,323.7 ms | 195.5 ms |
| 3 | 195.5 ms | 1,365.0 ms | 1,452.2 ms | 190.0 ms |
| 4 | 190.0 ms | 1,577.7 ms | 1,516.7 ms | 202.2 ms |
| 5 | 202.3 ms | 1,197.2 ms | 1,562.5 ms | 192.6 ms |
| 6 | 192.7 ms | 1,194.1 ms | 1,584.5 ms | 189.3 ms |
| 7 | 189.3 ms | 1,311.7 ms | 1,609.4 ms | 198.8 ms |
| 8 | 198.8 ms | 1,477.7 ms | 1,427.2 ms | 188.1 ms |
| 9 | 188.2 ms | 1,417.4 ms | 1,561.7 ms | 201.3 ms |
| 10 | 201.3 ms | 1,401.8 ms | 1,926.7 ms | 194.3 ms |
| 11 | 194.3 ms | 1,401.4 ms | 1,599.1 ms | 190.2 ms |
| 12 | 190.3 ms | 1,528.9 ms | 1,607.8 ms | 197.8 ms |
| 13 | 197.9 ms | 1,338.8 ms | 1,770.6 ms | 196.8 ms |
| 14 | 196.9 ms | 1,833.7 ms | 1,683.3 ms | 201.9 ms |
| 15 | 201.9 ms | 1,414.5 ms | 1,405.0 ms | 195.4 ms |
| 16 | 195.4 ms | 1,197.0 ms | 1,465.8 ms | 216.8 ms |
| 17 | 216.9 ms | 854.8 ms | 1,282.3 ms | 192.2 ms |
| 18 | 192.2 ms | 1,121.3 ms | 1,356.2 ms | 200.7 ms |
| 19 | 200.7 ms | 1,166.9 ms | 1,321.3 ms | 193.4 ms |
| 20 | 193.4 ms | 1,147.5 ms | 1,341.7 ms | 202.1 ms |
| 21 | 202.1 ms | 1,165.9 ms | 1,549.1 ms | 202.5 ms |
| 22 | 202.5 ms | 1,157.9 ms | 1,469.9 ms | 202.1 ms |
| 23 | 202.2 ms | 1,420.7 ms | 1,295.2 ms | 189.1 ms |
| 24 | 189.2 ms | 1,191.0 ms | 1,428.3 ms | 193.2 ms |
| 25 | 193.2 ms | 1,251.3 ms | 2,123.6 ms | 190.8 ms |
| 26 | 190.8 ms | 2,066.9 ms | 1,852.7 ms | 190.1 ms |
| 27 | 190.1 ms | 1,295.0 ms | 1,322.2 ms | 198.5 ms |
| 28 | 198.5 ms | 1,256.5 ms | 1,364.1 ms | 190.4 ms |
| 29 | 190.4 ms | 1,338.1 ms | 1,509.6 ms | 188.2 ms |
| 30 | 188.3 ms | 863.8 ms | 1,268.3 ms | 200.8 ms |
| 31 | 200.8 ms | 830.0 ms | 1,263.6 ms | 199.9 ms |
| 32 | 199.9 ms | 1,245.4 ms | 1,709.0 ms | 199.5 ms |
| 33 | 199.5 ms | 1,316.6 ms | 1,409.2 ms | 200.2 ms |
| 34 | 200.3 ms | 1,367.3 ms | 1,335.6 ms | 201.4 ms |
| 35 | 201.4 ms | 1,309.9 ms | 1,434.1 ms | 195.3 ms |
| 36 | 195.3 ms | 855.0 ms | 1,299.7 ms | 188.2 ms |
| 37 | 188.2 ms | 1,400.1 ms | 1,395.0 ms | 188.3 ms |
| 38 | 188.3 ms | 1,339.3 ms | 1,466.6 ms | 199.9 ms |
| 39 | 199.9 ms | 1,604.9 ms | 1,511.3 ms | 256.2 ms |
| 40 | 256.3 ms | 1,414.4 ms | 1,353.6 ms | 186.9 ms |
| 41 | 186.9 ms | 1,393.3 ms | 1,414.8 ms | 196.7 ms |
| 42 | 196.7 ms | 889.2 ms | 1,269.1 ms | 196.9 ms |
| 43 | 197.0 ms | 809.1 ms | 1,397.1 ms | 199.6 ms |
| 44 | 199.6 ms | 1,305.2 ms | 1,567.5 ms | 188.3 ms |
| 45 | 188.3 ms | 882.4 ms | 1,376.4 ms | 201.8 ms |
| 46 | 201.9 ms | 1,276.5 ms | 1,633.0 ms | 218.6 ms |
| 47 | 218.7 ms | 1,211.7 ms | 1,462.9 ms | 197.9 ms |
| 48 | 197.9 ms | 783.3 ms | 1,288.4 ms | 193.7 ms |
| 49 | 193.8 ms | 1,333.6 ms | 1,439.8 ms | 201.3 ms |
| 50 | 201.3 ms | 1,171.2 ms | 1,374.2 ms | 191.5 ms |
|=======|============|==============|================|============|
| avg | 194.0 ms | 1,249.7 ms | 1,474.4 ms | 197.6 ms |
|_______|____________|______________|________________|____________|
*** Average download speed for 42,700,800 bytes: 565.66 KB/s
C:\Data>
I'd welcome any suggestions to improve performance.
Thanks