My result for 2.000.000 lines compiled as x64 using compile parameter -gen gcc -Wc -Ofast -Wc -march=native -Wc -funroll-loops -Wc -mfpmath=sse -s gui:
The code:
Code: Select all
#Include "fbgfx.bi"
#include "string.bi"
Using FB
Const iW = 1200, iH = 600
Dim Shared As Any Ptr pScrn
Dim Shared As ULong Ptr pScrn2
'#Define PixelSet2Scrn(_x, _y, colour) *Cptr(Ulong Ptr, pScrn + (_y) * pitch + (_x) * imgData) = (colour)
Sub DrawLine0(x0 As Short, y0 As Short, x1 As Short, y1 As Short, col As Ulong) 'built-in line function
Line(x0, y0)-(x1, y1), Col
End Sub
Sub DrawLine1(x0 As Short, y0 As Short, x1 As Short, y1 As Short, col As Ulong) 'Bresenham Line Algorithm from Wikipedia
Dim As Short dx = Abs(x1 - x0), dy = -Abs(y1 - y0)
Dim As Byte sx = Iif(x0 < x1, 1, -1), sy = Iif(y0 < y1, 1, -1)
Dim As Short ierr = dx + dy, e2
Do
'PixelSet2Scrn(x0, y0, col)
pScrn2[y0 * iW + x0] = col
If (x0 = x1) Or (y0 = y1) Then Exit Do
e2 = ierr Shl 1
If (e2 >= dy) Then
ierr += dy
x0 += sx
End If
If (e2 <= dx) Then
ierr += dx
y0 += sy
End If
Loop
End Sub
Sub DrawLine2(x1 As Short, y1 As Short, x2 As Short, y2 As Short, col As Ulong) 'Bresenham Line Algorithm
Dim As Short xinc, yinc, x, y, dx, dy, e
dx = Abs(x2 - x1)
dy = Abs(y2 - y1)
If (x1 < x2) Then
xinc = 1
Else
xinc = -1
End If
If (y1 < y2) Then
yinc = 1
Else
yinc = -1
End If
x = x1
y = y1
'PixelSet2Scrn(x, y, col)
pScrn2[y * iW + x] = col
If (dx >= dy) Then
e = (dy Shl 1) - dx
While x <> x2
If e < 0 Then
e += dy Shl 1
Else
e += (dy - dx) Shl 1
y += yinc
End If
x += xinc
'PixelSet2Scrn(x, y, col)
pScrn2[y * iW + x] = col
Wend
Else
e = (dx Shl 1) - dy
While y <> y2
If e < 0 Then
e += dx Shl 1
Else
e += (dx - dy) Shl 1
x += xinc
End If
y += yinc
'PixelSet2Scrn(x, y, col)
pScrn2[y * iW + x] = col
Wend
End If
End Sub
Sub DrawLine3(x0 As Short, y0 As Short, x1 As Short, y1 As Short, col As Ulong) 'Xiaolin Wu
Dim As Boolean steep = Abs(y1 - y0) > Abs(x1 - x0)
Dim As Short t, dx, dy, e, ya, ys, x, y
If steep Then
t = x0 'swap x0, y0
x0 = y0
y0 = t
t = x1 'swap x1, y1
x1 = y1
y1 = t
End If
If x0 > x1 Then
t = x0 'swap x0, x1
x0 = x1
x1 = t
t = y0 'swap y0, y1
y0 = y1
y1 = t
End If
dx = x1 - x0
dy = Abs(y1 - y0)
e = dx Shr 1
ys = Iif(y0 < y1, 1, -1)
y = y0
For x = x0 To x1
If steep Then
'PixelSet2Scrn(y, x, col)
pScrn2[x * iW + y] = col
Else
'PixelSet2Scrn(x, y, col)
pScrn2[y * iW + x] = col
End If
e -= dy
If e < 0 Then
y += ys
e += dx
End If
Next
End Sub
'http://www.edepot.com/linee.html (Extremely Fast Line Algorithm Variation E)
Sub DrawLine4(x1 As Short, y1 As Short, x2 As Short, y2 As Short, col As Ulong) 'Po-Han Lin
Dim As Boolean yLonger = False
Dim As Long shortLen = y2 - y1, longLen = x2 - x1, decInc = 0, j, t
If Abs(shortLen) > Abs(longLen) Then
'Swap shortLen, longLen
t = shortLen
shortLen = longLen
longLen = t
yLonger = True
End If
If longLen <> 0 Then decInc = (shortLen Shl 16) / longLen
If yLonger Then
If longLen > 0 Then
longLen += y1
j = &h8000 + (x1 Shl 16)
While y1 <= longLen
'PixelSet2Scrn(j Shr 16, y1, col)
pScrn2[y1 * iW + (j Shr 16)] = col
j += decInc
y1 += 1
Wend
Exit Sub
End If
longLen += y1
j = &h8000 + (x1 Shl 16)
While y1 >= longLen
'PixelSet2Scrn(j Shr 16, y1, col)
pScrn2[y1 * iW + (j Shr 16)] = col
j -= decInc
y1 -= 1
Wend
Exit Sub
End If
If longLen > 0 Then
longLen += x1
j = &h8000 + (y1 Shl 16)
While x1 <= longLen
'PixelSet2Scrn(x1, j Shr 16, col)
pScrn2[(j Shr 16) * iW + x1] = col
j += decInc
x1 += 1
Wend
Exit Sub
End If
longLen += x1
j = &h8000 + (y1 Shl 16)
While x1 >= longLen
'PixelSet2Scrn(x1, j Shr 16, col)
pScrn2[(j Shr 16) * iW + x1] = col
j -= decInc
x1 -= 1
Wend
End Sub
Sub Benchmark(LineFn As Sub(x0 As Short = 0, y0 As Short = 0, x1 As Short = 0, y1 As Short = 0, col As Ulong = 0), l As Integer)
Dim As Ushort x1, y1, x2, y2
Dim As Ulong col
For i As Integer = 1 To l
x1 = Rnd() * (iW - 1)
y1 = Rnd() * (iH - 1)
x2 = Rnd() * (iW - 1)
y2 = Rnd() * (iH - 1)
col = Rnd() * &hFFFFFF
LineFn(x1, y1, x2, y2, &hFF000000 Or col)
Next
End Sub
Screenres iW, iH, 32, 2, GFX_WINDOWED Or GFX_NO_SWITCH Or GFX_ALWAYS_ON_TOP Or GFX_ALPHA_PRIMITIVES
ScreenSet 1, 0
Windowtitle("Line Benchmark")
pScrn = Screenptr()
pScrn2 = Screenptr()
Const iFn = 5
Dim As Integer i, l = 2000000
Dim As Double fTimer
Randomize Timer, 2
Dim As Double aResult(iFn - 1)
For i = 0 To iFn - 1
Windowtitle("Running function " & Str(i) & " with " & Format(l, "###,###,###,###") & " lines.")
Cls
fTimer = Timer
Select Case i
Case 0
Benchmark(@DrawLine0, l)
Case 1
Benchmark(@DrawLine1, l)
Case 2
Benchmark(@DrawLine2, l)
Case 3
Benchmark(@DrawLine3, l)
Case 4
Benchmark(@DrawLine4, l)
Case 5
End Select
aResult(i) = (Timer - fTimer) * 1000
Flip
Next
? "Result for " & Format(l, "###,###,###,###") & " lines:" : ?
For i = 0 To iFn - 1
? "Function " & i & ": " & aResult(i) & " ms"
Next
Flip
Do
Sleep(10, 1)
Loop Until Len(Inkey())